What is killing all WPF command CanExecutes?
-
I've encountered a strange problem in my WPF app. Basically, something appears to be killing all of my Command CanExecute methods. Every UI element that has a Command tied to it will be disabled after certain operations, while most other times they will function normally. Calling a dialog such as
MessageBox.Show("Really?", MessageBoxButton.YesNo)
then executing my code will cause the problem. Even UI elements with the most simple CanExecute such as this will be disabled after the dialog is shown.private void Cmd_Exit_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}Adding
CommandManager.InvalidateRequerySuggested();
into the methods does not help. Once they get disabled, clicking something active in the window will return normal behavior. I've exhausted all of the things that I know of to try to find out what is causing this problem. Where should I go from here? I feel that it's something in the bindings that is the problem but bringing up the debugger causes the behavior to change. -
I've encountered a strange problem in my WPF app. Basically, something appears to be killing all of my Command CanExecute methods. Every UI element that has a Command tied to it will be disabled after certain operations, while most other times they will function normally. Calling a dialog such as
MessageBox.Show("Really?", MessageBoxButton.YesNo)
then executing my code will cause the problem. Even UI elements with the most simple CanExecute such as this will be disabled after the dialog is shown.private void Cmd_Exit_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}Adding
CommandManager.InvalidateRequerySuggested();
into the methods does not help. Once they get disabled, clicking something active in the window will return normal behavior. I've exhausted all of the things that I know of to try to find out what is causing this problem. Where should I go from here? I feel that it's something in the bindings that is the problem but bringing up the debugger causes the behavior to change. -
Can you reproduce the problem in a very small, simple as possible app that reproduces the problem? Then post a complete set of snippets here such that others can use them to recreate an app to see the problem occur too.
Sincerely, -Ron
RNEELY, thanks for your reply. I will try to reproduce this in a sample app after I finish moving most of the code out of the window class and into the MasterList class. For the time being the entire source for the application is available: http://sourceforge.net/projects/subhub/[^] In my testing so far, the closest I have come to narrowing down the problem is in the following code block involving a MessageBox:
private void Cmd_CloseDir_Executed(object sender, ExecutedRoutedEventArgs e)
{
SetUiAsBusy();
if (MessageBox.Show(this, "Do you really...", "Confirm close", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
DirTreeNode theDirTreeNodeToRemove = MainTree_GetSelectedDirTreeNode();
MasterList.RemoveDirTreeNodeAndChildren(theDirTreeNodeToRemove, true);
MasterList.FillUniqueLists();
MasterList.FileMatches.Clear();
}
SetUiAsFree();
}When the method is run, if you select Yes from the MessageBox the problem will surface. If you select No then it will not. If I comment out the
if (MessageBox.Show
statement and just let the code run then the problem WILL NOT show up. From what I can tell, the problem seems to show up when dialogs and background processes are involved. I'll work to reproduce this in a sample this weekend. -
RNEELY, thanks for your reply. I will try to reproduce this in a sample app after I finish moving most of the code out of the window class and into the MasterList class. For the time being the entire source for the application is available: http://sourceforge.net/projects/subhub/[^] In my testing so far, the closest I have come to narrowing down the problem is in the following code block involving a MessageBox:
private void Cmd_CloseDir_Executed(object sender, ExecutedRoutedEventArgs e)
{
SetUiAsBusy();
if (MessageBox.Show(this, "Do you really...", "Confirm close", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
DirTreeNode theDirTreeNodeToRemove = MainTree_GetSelectedDirTreeNode();
MasterList.RemoveDirTreeNodeAndChildren(theDirTreeNodeToRemove, true);
MasterList.FillUniqueLists();
MasterList.FileMatches.Clear();
}
SetUiAsFree();
}When the method is run, if you select Yes from the MessageBox the problem will surface. If you select No then it will not. If I comment out the
if (MessageBox.Show
statement and just let the code run then the problem WILL NOT show up. From what I can tell, the problem seems to show up when dialogs and background processes are involved. I'll work to reproduce this in a sample this weekend. -
Did you make the application via the "WPF Application" template in Visual Studio 2008? If not try doing that then porting your source code over to the new app and see it it works. What does SetUiAsBusy() do?
Sincerely, -Ron
Yes, the app was made with the Wpf template. Here's the SetUiAsBusy method:
private void SetUiAsBusy()
{
MasterList.UiIsFree = false;
NotifyPropertyChanged_All();
CommandManager.InvalidateRequerySuggested();
}The SetUiAsFree method is the same except it is set to true. The UiIsFree variable is bound to the IsEnabled property of many UI elements. In the method I posted earlier,
MasterList.RemoveDirTreeNodeAndChildren(theDirTreeNodeToRemove, true);
is where nearly everything happens. Several ObservableCollections are modified (safely as best as I can tell) that are bound to UI elements. No exceptions are getting swallowed and the VS output pane remains empty while the method runs.