Sunday, May 1, 2011

How does one go about debugging databinding issues in MVVM?

I have rebuilt Josh Smith's CommandSink example from scratch and my version runs without error except that my command buttons are grayed out. I assume this is because there is something somewhere not set correctly so that the commands never get set to CanExecute = true or at some point get set to CanExecute = false.

But since the databinding is essentially going on in the XAML, I am not sure where to "set a breakpoint on the command" so I can see at what time a button is assigned CanExecute = false or e.g. is NOT assigned CanExecute = true.

Essentially I have these command bindings in a view:

<UserControl.CommandBindings>
    <sink:CommandSinkBinding Command="vm:CustomerViewModel.CloseCommand"/>
    <sink:CommandSinkBinding Command="vm:CustomerViewModel.ShowInformationCommand"/>
</UserControl.CommandBindings>

and in my CustomerViewModel the command is defined like this:

public static readonly RoutedCommand CloseCommand = new RoutedCommand();

public bool CanBeClosed
{
    get { return _customer.IsOpen; }
}

public void Close()
{
    _customer.IsOpen = false;

    this.OnPropertyChanged("CanBeClosed");
    this.OnPropertyChanged("CanBeApproved");
}

But since my understanding of MVVM right now is that you set up your M-VM-M, run your application and things "get data bound and just work".

I guess I am looking for something like a "Page Cycle" as in ASP.NET in which to step through to find out when my commands are CanExecute = true and when they are CanExecute = false.

How could one go about debugging an WPF/MVVM pattern like this where the databinding is not done explicitly in the code, and hence one cannot step-through debug in the classic sense?

Answer:

Although this article that Gishu mentioned was helpful in general regarding how to go about debugging databinding issues, and generally answered my question on how to do just that, it didn't help me in my particular case.

For what it's worth, I figured my particular issue with this code out by doing a line-per-line comparison with Josh Smith's original code and found these two lines that were missing from the CommandSinkBinding.OnCommandSinkChanged method:

if (!ConfigureDelayedProcessing(depObj, commandSink))
    ProcessCommandSinkChanged(depObj, commandSink);
From stackoverflow

0 comments:

Post a Comment