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

时间:2010-07-20 15:10:00

标签: silverlight mvvm silverlight-4.0 mvvm-light mvvm-toolkit

我创建了一个基于MVVM light toolkit的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}" />

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

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

如何解决此问题?

4 个答案:

答案 0 :(得分:2)

在MyCommand属性中添加一个setter。

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

此外,尝试添加测试值转换器并在convert方法中放置断点,以查看是否正在对该命令执行数据绑定。如果没有命中断点,您就知道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;
    }
}

答案 1 :(得分:2)

在我的机器上工作:)

说真的,我做了一个简单的项目,创建了一个ViewModel,粘贴在你的代码中,并且它有效。我猜你正在处理其他一些问题。

Here is my C# code.

Here is my XAML code.

时间传福音

此ViewModel代码令人厌恶。您可以考虑使用某种排序MVVM框架或帮助程序。例如,如果您查看ViewModelSupport,可以像这样编写ViewModel:

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

然后,你避免所有那些凌乱的管道。试想一下:)

答案 2 :(得分:0)

代码看起来很好。所以你只需要检查输出窗口是否存在数据绑定错误。也许你没有设置视图的datacontext正确。顺便说一句,你应该在命令的try-catch中添加你的断点。

答案 3 :(得分:0)

1)确保从中继命令的true代表返回CanExecute。 (我看到你这样做,但要仔细检查)。

2)按钮位于ListBoxDataGridDataForm

对于ListBox或DataGrid:

如果需要,您需要修改绑定表达式以引用VM DataContext而不是数据绑定项。 See this answer

对于DataForm:

更棘手,but look at this question.