如何在MVVM中调试数据绑定问题?

时间:2023-01-27 11:12:21

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.

我从头开始重建了Josh Smith的CommandSink示例,我的版本运行没有错误,只是我的命令按钮显示为灰色。我假设这是因为某些地方没有正确设置,所以命令永远不会设置为CanExecute = true或在某些时候设置为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.

但是由于数据绑定基本上是在XAML中进行的,我不知道在哪里“在命令上设置断点”所以我可以看到按钮被分配的时间CanExecute = false或者例如未分配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:

在我的CustomerViewModel中,命令定义如下:

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".

但是,由于我现在对MVVM的理解是你设置了你的M-VM-M,运行你的应用程序和事情“得到数据绑定并且正常工作”。

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.

我想我正在寻找类似ASP.NET中的“Page Cycle”之类的东西,在其中逐步查找我的命令是CanExecute = true以及它们何时为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?

怎么可以调试这样的WPF / MVVM模式,其中数据绑定没有在代码中明确地完成,因此在经典意义上不能逐步调试?

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.

虽然Gishu提到的这篇文章对于如何调试数据绑定问题一般有帮助,并且通常回答我关于如何做到这一点的问题,但在我的特定情况下它并没有帮助我。

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:

为了它的价值,我通过与Josh Smith的原始代码进行每行一次的比较来找出我的代码问题,并发现CommandSinkBinding.OnCommandSinkChanged方法中缺少这两行:

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

1 个解决方案

#1


First point:

To debug XAML Binding you can add reference to Diagnostics from WindowsBase dll to the XAML file, then when binding to some property add PresentationTraceSources.TraceLevel. When you run it check out the output window.

要调试XAML绑定,您可以将诊断从WindowsBase dll添加到XAML文件,然后在绑定到某些属性时添加PresentationTraceSources.TraceLevel。运行时,请检查输出窗口。

XAML sample :

XAML样本:

<TextBlock Text="{Binding someProperty, diagnostics:PresentationTraceSources.TraceLevel=High}"/>

Second point:

your command being grayed out means that your binding works! What doesn't happen is that the command doesn't refresh it's state, meaning CanExe() method ran and set the command to "can't exe state", however it never does check again if it can toggle its state back to "can exe". There are many ways to do it, but basically when a certain property changes in your ViewModel, refresh your command state:

你的命令灰显意味着你的绑定工作!没有发生的是该命令没有刷新它的状态,这意味着CanExe()方法运行并将命令设置为“无法执行exe状态”,但它永远不会再次检查它是否可以将其状态切换回“可以执行“。有很多方法可以做到这一点,但基本上当ViewModel中的某个属性发生变化时,请刷新命令状态:

in Prism, for example you can call someCommand.RaiseCanExecuteChanged ();

在Prism中,例如你可以调用someCommand.RaiseCanExecuteChanged();

#1


First point:

To debug XAML Binding you can add reference to Diagnostics from WindowsBase dll to the XAML file, then when binding to some property add PresentationTraceSources.TraceLevel. When you run it check out the output window.

要调试XAML绑定,您可以将诊断从WindowsBase dll添加到XAML文件,然后在绑定到某些属性时添加PresentationTraceSources.TraceLevel。运行时,请检查输出窗口。

XAML sample :

XAML样本:

<TextBlock Text="{Binding someProperty, diagnostics:PresentationTraceSources.TraceLevel=High}"/>

Second point:

your command being grayed out means that your binding works! What doesn't happen is that the command doesn't refresh it's state, meaning CanExe() method ran and set the command to "can't exe state", however it never does check again if it can toggle its state back to "can exe". There are many ways to do it, but basically when a certain property changes in your ViewModel, refresh your command state:

你的命令灰显意味着你的绑定工作!没有发生的是该命令没有刷新它的状态,这意味着CanExe()方法运行并将命令设置为“无法执行exe状态”,但它永远不会再次检查它是否可以将其状态切换回“可以执行“。有很多方法可以做到这一点,但基本上当ViewModel中的某个属性发生变化时,请刷新命令状态:

in Prism, for example you can call someCommand.RaiseCanExecuteChanged ();

在Prism中,例如你可以调用someCommand.RaiseCanExecuteChanged();