【问题标题】:How do you bind a Button Command to a member method?如何将按钮命令绑定到成员方法?
【发布时间】:2012-02-26 04:57:38
【问题描述】:

我的 MVVM WPF 实现中有一个 ListView,它有一个 DataTemplate,里面有一个按钮。 ListView 绑定到 ViewModel 中复杂对象的集合。

 <ListView ItemsSource="{Binding Path=ComplexObjects}"
          SelectedItem="{Binding Path=SelectedObject}"
          Width="Auto">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="My Property">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Margin="6,2,6,2">
                            <TextBlock Text="{Binding MyProperty}"/>
                        </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
    </GridViewColumn>
            <GridViewColumn Header="First Name">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Margin="6,2,6,2">
                            <Button Command="{Binding ???}"/>
                        </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
    </GridView>
</ListView.View>

所有文本字段都绑定没有问题,但是我可以将按钮命令绑定到 ComplexObject 的成员方法吗?如果是的话有什么方法可以传递参数吗?

我有一种感觉,我可能只是在逃避使用 ICommand。

谢谢。

【问题讨论】:

标签: c# wpf listview data-binding mvvm


【解决方案1】:

您可以在 ViewModel 上绑定 ICommand,将实例作为参数传递给调用方法。然后 ViewModel 可以调用右侧的相应方法ComplexObject

例如:

<DataTemplate>
    <StackPanel Margin="6,2,6,2">
        <Button Command="{Binding DoSomethingCommand, RelativeSource={RelativeSource AncestorType={x:Type ViewModelType}, Mode=FindAncestor}" CommandParameter="{Binding}"/>
    </StackPanel>
</DataTemplate>

那么视图模型可能如下所示:

public ICommand DoSomethingCommand
{
    get { return new DelegateCommand<object>(DoSomething); }
}

private void DoSomething(object instance)
{
    var complexObject = instance as ComplexObject;
    if (complexObject != null)
        complexObject.SomeMethod();
}

【讨论】:

  • 就像答案一样,此时我无法让绑定工作
  • 知道了,但我没有使用 RelativeSource 只是 {Binding ElementName=nameOfListView, Path=DataContext.DoSomethingCommand}
  • Answer 也可以在 DelegateCommand 周围使用一些解释,我以前用过,但其他人可能没有。谢谢!
  • 我很高兴你让它工作了,你的解决方案可能比遍历树更有效。
【解决方案2】:

如果您真的想发疯,我想您可以使用delegate 的依赖属性创建自己的按钮自定义控件,然后您可以绑定到返回相同类型delegate 的属性。然后在您的自定义控件类中,您可以在单击时调用委托。


总是有标准的 ICommand,如果你走那条路,这就是……

<Button Command={Binding CommandProperty} />

使用 Kent Boogaart 的 blog post 中的 DelegateCommand 类。 那么……

在您要绑定的类中:

private ICommand _commandField;

public ICommand CommandProperty
{
  get
  {
    if (_commandField == null) _commandField = new DelegateCommand(CommandMethod);

    return _commandField;
  }
}

private void CommandMethod() 
{
  // do stuff...
}

【讨论】:

  • 我认为提问者试图避免在每个ComplexObject 上使用ICommand,并且正在寻找一种直接调用方法的方法。
【解决方案3】:

对于 Button,您需要使用在您的 ComplexObject 中建立的 ICommand:

<Button Command="{Binding Path = CommandName}"/>

如果您的方法位于包含 ComplexObjects 集合的视图模型中,则将您的控件或窗口命名为 Me 并使用如下内容:

<Button Command="{Binding ElementName=Me, Path=DataContext.CommandName}" />

您可以使用单击或向下预览鼠标,但如果您想在 XAML 中绑定方法,您仍然需要将该事件路由到命令。只是绑定命令更容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2013-09-16
    • 2012-09-07
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多