无法将 VM 中的 ICommand 绑定到 xaml 中的按钮 Command

发布于 2024-09-10 18:58:23 字数 1048 浏览 2 评论 0原文

我创建了一个基于MVVM light工具包的VM。 在VM中,有一个简单的ICommand(RelayCommand),

  private RelayCommand _myCommand = null;
    public RelayCommand MyCommand
    {
        get
        {
            if (_myCommand == null)  //set break point here for debug
            {
                _myCommand = new RelayCommand(() =>
                {
                    try
                    {
                       //....
                    }
                    catch (Exception ex)
                    {
                        // notify user if there is any error
                        //....
                    }
                }
                , () => true);
            }
            return _myCommand;
        }
    }

然后在xaml中,只需将此Command属性绑定到一个按钮,例如:

 <Button Grid.Column="1"  x:Name="Test" Content="Test" Margin="2,0,2,0" Command="{Binding Path=MyCommand}" />

然后运行应用程序,然后单击按钮,根本没有响应。没有错误。 虚拟机工作正常。在单击“测试”按钮之前,数据已加载到数据网格中。

如果调试应用程序并设置断点,则永远不会到达该点。

如何解决这个问题?

I create a VM based on MVVM light toolkit.
In VM, there is a simple ICommand(RelayCommand)

  private RelayCommand _myCommand = null;
    public RelayCommand MyCommand
    {
        get
        {
            if (_myCommand == null)  //set break point here for debug
            {
                _myCommand = new RelayCommand(() =>
                {
                    try
                    {
                       //....
                    }
                    catch (Exception ex)
                    {
                        // notify user if there is any error
                        //....
                    }
                }
                , () => true);
            }
            return _myCommand;
        }
    }

then in xaml, just bind this Command property to a button like:

 <Button Grid.Column="1"  x:Name="Test" Content="Test" Margin="2,0,2,0" Command="{Binding Path=MyCommand}" />

Then run the app, and click on the button, there is no response at all. No error.
VM is working fine. The data has been loaded to a datagrid before I click on the Test button.

If debug the app and put break point, the point is never reached.

How to resolve this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请持续率性 2024-09-17 18:58:24

1) 确保从中继命令的 CanExecute 委托返回 true。 (我看到你正在这样做,但最好仔细检查一下)。

2) 按钮是否位于 ListBoxDataGridDataForm 内?

对于ListBox或DataGrid:

如果是这样,您需要修改绑定表达式以引用VM DataContext而不是数据绑定项。 查看此答案

对于 DataForm :

更棘手,但是看看这个问题。

1) Make sure you're returning true from the relay command's CanExecute delegate. (I see you are doing this but good to double check).

2) Is the button inside a ListBox, DataGrid or DataForm?

For a ListBox or DataGrid:

If so you need to modify your binding expression to refer to the VM DataContext as opposed to the databound item. See this answer.

For a DataForm :

More tricky, but look at this question.

彼岸花似海 2024-09-17 18:58:23

将 setter 添加到您的 MyCommand 属性。

与往常一样,在呈现 XAML 时检查“输出”窗口是否有任何数据绑定错误。

另外,尝试添加一个测试值转换器并在转换方法中放置一个断点,以查看是否正在该命令上执行数据绑定。如果未命中断点,则表明 XAML 中存在问题。如果命中断点,请查看该值以查看数据上下文是否正确。

<UserControl.Resources>
    <ResourceDictionary>
        <TestConverter x:Key="TestConverter" />
    </ResourceDictionary>
    <Button Grid.Column="1" x:Name="Test" Content="Test" Margin="2,0,2,0" Command="{Binding Path=MyCommand, Converter={StaticResource TestConverter}}" />
</UserControl>

测试值转换器 - 对于调试数据绑定问题非常有用。

public class TestConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("TestConverter.Convert(value := {0}, targetType := {1}, parameter := {2}, culture := {3})",
            value, targetType, parameter, culture);
        return value; // put break point here to test data binding
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("TestConverter.ConvertBack(value := {0}, targetType := {1}, parameter := {2}, culture := {3})",
            value, targetType, parameter, culture);
        return value;
    }
}

Add a setter to your MyCommand property.

As always, check the Output window for any data binding errors when the XAML is rendered.

Also, try adding a test value converter and putting a breakpoint in the convert method to see if data binding is even being executed on that command. If the breakpoint isn't hit, you know you have a problem in your XAML. If the breakpoint is hit, take a look at the value to see if the data context is correct.

<UserControl.Resources>
    <ResourceDictionary>
        <TestConverter x:Key="TestConverter" />
    </ResourceDictionary>
    <Button Grid.Column="1" x:Name="Test" Content="Test" Margin="2,0,2,0" Command="{Binding Path=MyCommand, Converter={StaticResource TestConverter}}" />
</UserControl>

Test value converter - very useful for debugging data binding issues.

public class TestConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("TestConverter.Convert(value := {0}, targetType := {1}, parameter := {2}, culture := {3})",
            value, targetType, parameter, culture);
        return value; // put break point here to test data binding
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debug.WriteLine("TestConverter.ConvertBack(value := {0}, targetType := {1}, parameter := {2}, culture := {3})",
            value, targetType, parameter, culture);
        return value;
    }
}
不再让梦枯萎 2024-09-17 18:58:23

在我的机器上工作:)

说真的,我做了一个简单的项目,创建了一个 ViewModel,粘贴到你的代码中,它工作了。我猜您正在处理其他问题。

这是我的 C# 代码。

这是我的 XAML 代码。

是时候宣传一下了

这个 ViewModel 代码很臭。您可能会考虑使用某种 MVVM 框架或助手。如果您查看 ViewModelSupport例如,您可以这样编写 ViewModel:

public class MyViewModel : ViewModelBase
{
    public void Execute_MyCommand()
    {
        // Your execution code here
    }
}

然后,您就可以避免所有混乱的管道。想想看:)

Works on my machine :)

Seriously, I made a simple project, created a ViewModel, pasted in your code, and it worked. I am guessing you are dealing with some other issue.

Here is my C# code.

Here is my XAML code.

Time to evangelize a bit

This ViewModel code reeks. You might consider using some sort MVVM framework or helpers. If you look at ViewModelSupport, for instance, you can write your ViewModel like this:

public class MyViewModel : ViewModelBase
{
    public void Execute_MyCommand()
    {
        // Your execution code here
    }
}

Then, you avoid all that messy plumbing. Just think about it :)

記憶穿過時間隧道 2024-09-17 18:58:23

代码看起来不错。因此您只需检查输出窗口是否有数据绑定错误。也许您没有正确设置视图的数据上下文。顺便说一句,您应该在命令的 try-catch 中添加断点。

the code looks fine. so you just have to check the output window for databinding errors. maybe you did not set the datacontext of the view correct. btw you should add your breakpoint in the try-catch of the command.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文