wpf отчего может RelayCommand делать кнопку IsEnabled=false
От: okon  
Дата: 04.11.16 14:36
Оценка:
Есть RelayCommand из MvvmLight на него забиндена кнопка, вроде как все работает.


public RelayCommand MyCommand {get;}

public MyClass( IMyInterface service)
{
    MyCommand = new RelayCommand(()=>DoSomething(), ()=> 

    {  
       Debug.Writeline("CanExecute");
       var result = service.Check();
       Debug.Writeline("CanExecute {result}");      
       return result;
    });

}


Но в определенных обстоятельствах кнопка становится IsEnabled=false, причем стоят логи на CanExecute и его вызов в момент Disable не происходит последний залогированный вызов — true.
Стили все убраны, стандартные.
В output пишутся все события binding, там ничего нету из ошибок , есть немного Information 10 что хотят FallbackValue, но насколько мне известно это биндинги не ломает.
Как отладить из-за чего состояние кнопки меняется на disabled ?
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Отредактировано 04.11.2016 14:36 okon . Предыдущая версия .
Re: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: anatolym  
Дата: 04.11.16 16:08
Оценка:
Здравствуйте, okon, Вы писали:

У них есть 2 namespace: GalaSoft.MvvmLight.Command и GalaSoft.MvvmLight.CommandWpf. Если ты работаешь с WPF, то нужно использовать класс Command из GalaSoft.MvvmLight.CommandWpf. В противном случае могут быть проблемы с обновлением состояния IsEnabled.
Отредактировано 04.11.2016 16:12 anatolym . Предыдущая версия .
Re[2]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: okon  
Дата: 04.11.16 16:23
Оценка:
Здравствуйте, anatolym, Вы писали:

A>Здравствуйте, okon, Вы писали:


A>У них есть 2 namespace: GalaSoft.MvvmLight.Command и GalaSoft.MvvmLight.CommandWpf. Если ты работаешь с WPF, то нужно использовать класс Command из GalaSoft.MvvmLight.CommandWpf. В противном случае могут быть проблемы с обновлением состояния IsEnabled.


Да хорошая идея, но к сожалению везде CommandWpf.
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[3]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: anatolym  
Дата: 04.11.16 16:42
Оценка:
Здравствуйте, okon, Вы писали:

Насчет того как отладить подсказать не могу. Но можно пройтись по списку возможных поставщиков для свойства зависимости, и проверить наличие их в программе для свойства IsEnabled.
Ну еще можно код показать (выложить проект, если небольшой), может быть что-то смогу там найти
Re[3]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: MxMsk Португалия  
Дата: 05.11.16 07:07
Оценка:
Здравствуйте, okon, Вы писали:

O>Да хорошая идея, но к сожалению везде CommandWpf.

Как вариант, попробуй подписаться на событие IsEnabledChanged и посмотреть по стеку, что его вызвало.
Re[4]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: okon  
Дата: 05.11.16 08:20
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Здравствуйте, okon, Вы писали:


O>>Да хорошая идея, но к сожалению везде CommandWpf.

MM>Как вариант, попробуй подписаться на событие IsEnabledChanged и посмотреть по стеку, что его вызвало.

Да поймалось, в callstack вижу следующее, т.е. получается все так CanExecute откуда-то вызывается но видимо не в том объекте где я ожидаю. Проверил не меняется ли DataContext кнопки , контекст не изменяется остается прежним.

PresentationCore.dll!System.Windows.UIElement.RaiseDependencyPropertyChanged(System.Windows.EventPrivateKey key, System.Windows.DependencyPropertyChangedEventArgs args) Unknown
PresentationCore.dll!System.Windows.UIElement.OnIsEnabledChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e) Unknown
WindowsBase.dll!System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) Unknown
PresentationFramework.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e) Unknown
WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) Unknown
WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex, System.Windows.DependencyProperty dp, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry, bool coerceWithDeferredReference, bool coerceWithCurrentValue, System.Windows.OperationType operationType) Unknown
WindowsBase.dll!System.Windows.DependencyObject.CoerceValue(System.Windows.DependencyProperty dp) Unknown

PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.CanExecute.set(bool value) Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute() Unknown
PresentationFramework.dll!System.Windows.Controls.Primitives.ButtonBase.OnCanExecuteChanged(object sender, System.EventArgs e) Unknown

PresentationCore.dll!System.Windows.Input.CanExecuteChangedEventManager.HandlerSink.OnCanExecuteChanged(object sender, System.EventArgs e) Unknown
WindowsBase.dll!System.Windows.WeakEventManager.ListenerList.DeliverEvent(ref System.Windows.WeakEventManager.Listener listener, object sender, System.EventArgs args, System.Type managerType) Unknown
WindowsBase.dll!System.Windows.WeakEventManager.ListenerList.DeliverEvent(object sender, System.EventArgs args, System.Type managerType) Unknown
WindowsBase.dll!System.Windows.WeakEventManager.DeliverEvent(object sender, System.EventArgs args) Unknown
PresentationCore.dll!System.Windows.Input.CommandManager.RequerySuggestedEventManager.OnRequerySuggested(object sender, System.EventArgs args) Unknown
PresentationCore.dll!System.Windows.Input.CommandManager.RaiseRequerySuggested(object obj) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl() Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(object state) Unknown
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Unknown
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Unknown
WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue() Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs) Unknown
WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler) Unknown
WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs) Unknown
WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam) Unknown

”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[5]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: okon  
Дата: 05.11.16 14:01
Оценка:
Здравствуйте, okon, Вы писали:

O>Здравствуйте, MxMsk, Вы писали:


MM>>Здравствуйте, okon, Вы писали:


O>>>Да хорошая идея, но к сожалению везде CommandWpf.

MM>>Как вариант, попробуй подписаться на событие IsEnabledChanged и посмотреть по стеку, что его вызвало.

O>Да поймалось, в callstack вижу следующее, т.е. получается все так CanExecute откуда-то вызывается но видимо не в том объекте где я ожидаю. Проверил не меняется ли DataContext кнопки , контекст не изменяется остается прежним.


В общем разгадка похоже в жизненном цикле объекта, только пока не ясно как он повлиял на жизнь лябмды

Т.е. вот так получается через некоторое время Debug.WriteLine("CanExecute") лямбды не вызывается.
При этом у самой кнопки у команды событие CanExecuteChanged приходит и если вызвать так Button.Command.CanExecute(null) то возвращается false, но в указанную в констукторе MyClass лямбду не заходит ( т.е. Debug.WriteLine("CanExecute") не вызывается ).
Т.е. такое ощущение что лямбда заменяется каким-то другим выражением.



public RelayCommand MyCommand {get;}

public MyClass( IMyInterface service)
{
    MyCommand = new RelayCommand(()=>DoSomething(), ()=> 

    {  
       Debug.Writeline("CanExecute");
       var result = service.Check();
       Debug.Writeline("CanExecute {result}");      
       return result;
    });

}



Если же написать вот так, то все работает как ожидается.

public RelayCommand MyCommand {get;}

private IMyInterface _service;

public MyClass( IMyInterface service)
{
    _service = service;

    MyCommand = new RelayCommand(()=>DoSomething(), ()=> 

    {  
       Debug.Writeline("CanExecute");
       var result = _service.Check();
       Debug.Writeline("CanExecute {result}");      
       return result;
    });

}
”Жить стало лучше... но противнее. Люди которые ставят точку после слова лучше становятся сторонниками Путина, наши же сторонники делают акцент на слове противнее ( ложь, воровство, лицемерие, вражда )." (с) Борис Немцов
Re[6]: wpf отчего может RelayCommand делать кнопку IsEnabled=fa
От: MxMsk Португалия  
Дата: 06.11.16 10:50
Оценка:
Здравствуйте, okon, Вы писали:

O>Если же написать вот так, то все работает как ожидается.

Было у меня что-то подобное на StackOverflow. Попробуй просто обойтись без лямбды, сделав нормальный метод в MyClass.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.