WPF:如何通过XAML将整个Control作为CommandParameter传递?

时间:2010-08-14 06:49:32

标签: c# wpf xaml

我正在使用MVVM,ViewModel层提供自定义ICommand对象。一个ViewModel对象可以通过DataContext属性连接到许多View对象(窗口,页面等)。在ICommand.CanExecute()中,我想检查View中某些控件的缺省验证错误(附加到ViewModel道具,对于特定的VM命令很重要)。一个ViewModel可以提供许多命令,每个命令都有自己的一组控件用于错误验证验证。所以,伪XAML是:

<Button.CommandParameter>
    <x:Array Type="sys_win:DependencyObject">
        <sys_win:DependencyObject>
            <reference_to_textbox_or_other_control/>
        </sys_win:DependencyObject>
        <sys_win:DependencyObject>
            <reference_to_textbox_or_other_control/>
        </sys_win:DependencyObject>
    </x:Array>
</Button.CommandParameter>

第二个问题是控件可以调用特定命令,控件本身就是DataTemplate for collection项的一部分(在我的例子中是ListBoxItem数据模板的一部分)。我的模板化列表框项目有两个文本框(绑定到相应ViewModel的两个道具)和按钮,它们调用ViewModel命令。因此,在命令CanExecute()中,我需要检查某些窗口控件的验证错误。两个文本框,属于此listitem,不属于其他项目。如果我想将ListBoxItem.IsSelected属性作为CommandParameter传递,下面的代码工作正常:

<Button DataContext="{Binding}" 
        Command="{Binding Path=SwitchCommand}"
        CommandParameter="{Binding Path=IsSelected, RelativeSource={
                                   RelativeSource
                                   Mode=FindAncestor,
                                   AncestorType={x:Type ListBoxItem}}}"/>

但是如何将整个(DependencyObject)ListBoxItem作为CommandParameter传递?以及如何通过{Binding RelativeSource}传递的ListBoxItem可以与第一个代码示例中的其他当前窗口控件混合使用?


我很抱歉,但是如何在xaml中添加对控件的引用?

<Button.CommandParameter>
    <x:Array Type="sys_win:DependencyObject">
        <sys_win:DependencyObject>
            <reference_to_textbox_or_other_control/>
        </sys_win:DependencyObject>
        <sys_win:DependencyObject>
            <reference_to_textbox_or_other_control/>
        </sys_win:DependencyObject>
    </x:Array>
</Button.CommandParameter>

2 个答案:

答案 0 :(得分:27)

只使用没有Path的绑定:

<Button DataContext="{Binding}" 
        Command="{Binding Path=SwitchCommand}"
        CommandParameter="{Binding RelativeSource=
                                   {RelativeSource
                                    Mode=FindAncestor,
                                    AncestorType={x:Type ListBoxItem}}}"/>

答案 1 :(得分:1)

我不确定我是否正确阅读了您的示例,但它似乎违反了一些MVVM原则。 (如果我读错了,我很抱歉。)

MVVM背后的想法是将视图模型与对XAML / View实体的任何依赖性分离。您可以通过让CommandParameter依赖于usercontrol来破坏它。我要做的是在ViewModel中创建状态属性并将usercontrol验证绑定到这些状态,然后在CanExecute中,您可以测试这些属性的值,而不是尝试绑定到用户控件。