最终说明 Final solution found in another post
虽然我对所提供的澄清表示赞赏,但最终的解决方案实际上是由上面提到的另一种解决方案提供的。无论我尝试什么,通过“元素名称”组件绑定都无法正常工作。我必须基于datagrid的“Relative”层次结构...
<Button Name="btnPrintReport"
Command="{Binding DataContext.MyPrintCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Height="16" Width="16" HorizontalAlignment="Center" >
<Image Source="MyButtonImage.png" IsHitTestVisible="True"/>
</Button>
希望在WPF / MVVM环境中不会太复杂。这是场景。
我有一个Window(.xaml)和一个相应的View Model(.cs)。表单显示正常,所有数据绑定都没问题。 (注意:这不是通过任何商业“框架”完成的)
视图窗口中的一个控件是数据网格的自定义用户控件,其中包含在显示视图时显示的所有预定义列,标题和内容。即使控件没有在主窗口.xaml文件中直接“定义”,但是只是作为用户控件本身(它有自己明显的.cs代码隐藏)放在窗体上,这一切都没有问题。
主窗口的“DataContext”指向View Model,以及具有datagrid的用户控件
<DataGrid AutoGenerateColumns="False"
Name="dataMyStuff"
ItemsSource="{Binding Path=MyTablePropertyOnViewModel,
NotifyOnSourceUpdated=True,
NotifyOnTargetUpdated=True}" ... />
现在,我正在寻找什么。在这个数据网格上,我有一个在第一列中有图像的列。当我点击这个图像时,我想打印一个特定于该行所代表的记录的报告(它具有我使用的PK值)。那么,我如何告诉图像“KeyUp”事件转到View Model事件处理程序,因为那是数据所在的位置,以及我准备调用报表所需的其他一些方法。网格的视图部分用于向用户显示化妆品,因此在该控件中不直接显示“功能”。
- 编辑 - 每个答案的进展
我根据Josh和Rachel的评论调整了我的数据网格,然而,某些东西看起来仍然不太正确......看到按钮正在使用“Command”实例,我将其解释为需要附加到我的视图模型上的“ICommand”接口对象的实例。所以,我创建了一个实例。我知道命令处理程序的工作原理,因为它也用于常见的事情,如添加,编辑,保存,取消,退出等...所以我有一个新的打印目的。为简单起见,我将它创建为Always Execute,因此没有方法来处理控件的“CanExecute”部分。我已经将按钮的“命令”设置为几乎所有我仍然无法想到的迭代,但这里是我正在看到的更新。
<UserControl>
<Data grid columns / template, etc to the button>
<DataTemplate>
<Button Name="btnPrintReport"
Command="{Binding DataContext.MyPrintCommand}" >
<Image Source="myPrintImage.png"/>
</Button>
</DataTemplate>
</Data grid columns, etc>
</UserControl>
在我的ViewModel类中(myICommandButtonHandler继承自ICommand)
private myICommandButtonHandler myPrintCommand;
public myICommandButtonHandler MyPrintCommand
{
get { if (myPrintCommand == null)
myPrintCommand = new myICommandButtonHandler(myPrint);
return myPrintCommand;
}
}
private void myPrint()
{
MessageBox.Show( "Doing the print job..." );
}
现在,我所看到的。在逐步初始化所有控件等过程中。我点击菜单项来调用我的窗口进行显示。首先,它创建一个View Model控制器的实例。然后,它调用Window并将View Model控制器作为参数传递,因此它立即在Window级别设置为窗口的“DataContext”。然后主窗口进入它的“InitializeComponents”调用并开始构建嵌入的所有其他控件,包括包含相关数据网格的这个单独的类。在这个usercontrol(具有datagrid)的构造函数中,没有设置“数据上下文”,因为其余的控件尚未初始化,我不知道为什么/何时“绑定”显然得到“因此,似乎尝试绑定到数据网格的命令按钮失败了。然而,在运行时,实际数据在网格中更新,所以我知道有很多工作。
因此,数据网格的“ItemsSource”设置为视图模型上“DataView”属性的属性,但“按钮”的绑定似乎没有看到我认为的“MyPrintCommand”处理程序得到命中..它的动作是只显示一个消息框(现在)。
答案 0 :(得分:2)
通常我使用AttachedCommand Behavior,它允许我将事件绑定到ViewModel命令。例如,您可以使用
<Image ...
local:CommandBehavior.Event="KeyUp"
local:CommandBehavior.Command="{Binding DataContext.PrintCommand, ElementName=dataMyStuff}"
local:CommandBehavior.CommandParameter="{Binding }"/>
我建议使用与KeyUp不同的事件,因为我不认为图像可以具有键盘焦点,因此KeyUp事件永远不会被触发。
更好的选择是使用Button并将其模板覆盖为您的Image。这将保留Click
功能,并允许您访问Command
和CommandParameter
属性
<Button Command="{Binding DataContext.PrintCommand, ElementName=dataMyStuff}"
CommandParameter="{Binding }">
<Button.Template>
<Image ... />
</Button.Template>
</Button>
此外,CommandParameter="{Binding }"
只会将当前DataRow的DataContext(您的数据对象)传递给命令
答案 1 :(得分:1)
将数据模板更改为以图像为内容的按钮。使用按钮上的命令和命令参数属性来调用打印方法。您可以在viewmodel中声明print命令,然后绑定到它。您的参数可以是数据网格中的选定行。