来自 ItemsControl 项目的 RelayCommand 发送者
我一直在使用 MVVM 的 RelayCommand 成功地将操作绑定到 XAML,但我的 ItemsControl 遇到了一个小问题。
<ItemsControl ItemsSource="{Binding Devices}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="100" Margin="4" >
<Button Command="{Binding Path=SelectDeviceCommand}" >
<Grid>
<Image Source="img_small.png"></Image>
<Image Source="{Binding Path=Logo}" />
</Grid>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在我的视图模型中:
public RelayCommand SelectDeviceCommand { get; set; }
private ObservableCollection<Device> Devices;
Devices = CreateListOfDevices();
private void InitializeCommands()
{
SelectDeviceCommand = new RelayCommand((s) => MessageBox.Show(s.ToString()));
}
如何在视图模型中定义 SelectDeviceCommand 以接收绑定到该项目的对象?
我的 SelectDeviceCommand 甚至没有被调用...(但我猜是因为我需要使我的设备成为迷你视图模型并在其中实现 SelectDeviceCommand,对吗?)
I've been using MVVM's RelayCommand with success to bind actions to XAML, but I'm having a small problem with my ItemsControl.
<ItemsControl ItemsSource="{Binding Devices}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="100" Margin="4" >
<Button Command="{Binding Path=SelectDeviceCommand}" >
<Grid>
<Image Source="img_small.png"></Image>
<Image Source="{Binding Path=Logo}" />
</Grid>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In my view model:
public RelayCommand SelectDeviceCommand { get; set; }
private ObservableCollection<Device> Devices;
Devices = CreateListOfDevices();
private void InitializeCommands()
{
SelectDeviceCommand = new RelayCommand((s) => MessageBox.Show(s.ToString()));
}
How do I define my SelectDeviceCommand in my view model in order to receive object that is bound to that item?
My SelectDeviceCommand is not even being called... (but that I guess is because I need to make my Device a mini-viewmodel and implement the SelectDeviceCommand in it, is that correct?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您像在 MVVM Light 应用程序中一样使用 ViewModelLocator,则可以从 DataTemplate 中获取对 MainViewModel 的引用,
我发现这种方式比 ElementName 更清晰,但当然它假设 Main 属性在定位器中可用,并且另外 MainviewModel 被实例化为单例。显然,这并不总是可能的。在这种情况下,我认为 ElementName 解决方法是可以接受的。
在WPF中,您还可以使用Mode=FindAncestor的RelativeSource,但我发现它更混乱;)
关于“如何在视图模型中定义我的SelectDeviceCommand以便接收绑定到该项目的对象?”的问题,我不能 100% 确定我理解这个问题,但如果您想获取 DataTemplate 表示的项目(在本例中为设备),您应该使用 CommandParameter:
干杯,
洛朗
If you use a ViewModelLocator like in MVVM Light applications, you can get a reference to the MainViewModel from within the DataTemplate with
I find this way cleaner than the ElementName one, but of course it supposes that the Main property is available in the locator, and also that the MainviewModel is instantiated as a singleton. This is not always possible, obviously. In that case, I consider the ElementName workaround acceptable.
In WPF, you can also use a RelativeSource with Mode=FindAncestor, but I find it even messier ;)
Regarding the question "How do I define my SelectDeviceCommand in my view model in order to receive object that is bound to that item?", I am not 100% sure that I understand the question, but if you want to get the item (in this case a Device) that is represented by the DataTemplate, you should use the CommandParameter:
Cheers,
Laurent
是的,这个我已经打过了。我见过一些人使用自定义的“CommandReference”类来解决这个问题,他们将其作为资源添加到窗口中,但我无法让它工作。
最后,我使用元素绑定回窗口(或页面)本身,因为 ViewModel 是窗口的 DataContext。首先,为您的窗口(或页面)命名:
然后直接绑定到窗口的数据上下文,如下所示:
这对我有用。虽然很乱,但我认为它很可读。
Yeah, I've struck this one. I've seen some people work around it with a custom "CommandReference" class that they add as a resource to the window, but I couldn't get that to work.
In the end, I used element binding back to the window (or page) itself, since the ViewModel is the DataContext of the window. First, give your window (or page) a name:
Then bind to the window's datacontext directly, like this:
This has worked for me. It's messy, but I think it's pretty readable.
我有一个 usercontrol(x:Name="ControlClass") 并且它位于模板内,它不适用于 xaml
我这样称呼它
I have a usercontrol(x:Name="ControlClass") and it is inside a template, it doesnt work on xaml
i called it like this