简体   繁体   中英

Dealing with commands in WPF

I am trying to handle a command. In my simple application I have a textbox named txtEditor . In the code there is a problem that I do not know why it happens.
Whenever I run the following code, it executes well.

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (txtEditor != null)
        e.CanExecute = (txtEditor.Text != null) && (txtEditor.SelectionLength > 0);
}

But for the following code:

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{    
    e.CanExecute = (txtEditor.Text != null) && (txtEditor.SelectionLength > 0);
}

I get this Error:

{"Object reference not set to an instance of an object."}

I have bound the command to the CommandBindings of Window Collection.
The problem is that I do not know the reason why this error happens, if txtEditor is not initialized, so what does method InitializeComponent() do in the constructor of WPF window?
And also When are the commands called that this error happens?

This happens because the CanExecute event is fired independently from your window intialization whenever CommandManager.RequerySuggested event is triggered. That's why it is not guaranteed that it will be fired after InitializedComponent() is called.

You can easily check this by handling your windows' Initialized event:

private void MainWindow_Initialized(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("MainWindow initialized");
}

private void CutCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine("CommandBinding_CanExecute fired");
}

By doing so you will notice that CanExecute is fired before your window is actually initialized and in the output window you will see:

CommandBinding_CanExecute fired
MainWindow initialized
CommandBinding_CanExecute fired
CommandBinding_CanExecute fired

Before InitializeComponent() is called, txtEditor is null. Inside this method all the UI elements gets initialized:

this.txtEditor = ((System.Windows.Controls.TextBox)(target));

After the call it will not be null, it will be System.Windows.Controls.TextBox . You are trying to access an object which is referring to null.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM