我一直在使用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,这是正确的吗?)
答案 0 :(得分:4)
如果您在MVVM Light应用程序中使用ViewModelLocator,则可以使用
从DataTemplate中获取对MainViewModel的引用<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}">
我发现这种方式比ElementName更清晰,但当然它假设Main属性在定位器中可用,并且MainviewModel也被实例化为单例。显然,这并不总是可行的。在这种情况下,我认为ElementName解决方法是可以接受的。
在WPF中,您也可以使用具有Mode = FindAncestor的RelativeSource,但我发现它更加混乱;)
关于“如何在我的视图模型中定义我的SelectDeviceCommand以接收绑定到该项目的对象?”的问题,我不是百分之百确定我理解这个问题,但如果你想得到由DataTemplate表示的item(在本例中为Device),您应该使用CommandParameter:
<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}"
CommandParameter="{Binding}"}">
干杯, 劳伦
答案 1 :(得分:0)
最后,我使用元素绑定回到窗口(或页面)本身,因为ViewModel是窗口的DataContext。首先,给你的窗口(或页面)命名:
<Window ...
x:Name="me" />
然后直接绑定到窗口的datacontext,如下所示:
<Button Command="{Binding DataContext.SelectDeviceCommand,ElementName=me}">
这对我有用。它很乱,但我觉得它很可读。
答案 2 :(得分:0)
我有一个usercontrol(x:Name =“ControlClass”)并且它在模板内部,它在xaml上不起作用 我这样叫它
<Button Content="New1" Command="{Binding DataContext.NewTabCommand,ElementName=ControlClass}"/>
namespace Doit_Project.Modules.Tasks.ViewModels
{
[Export]
public class WindoTabViewModel : Doit_ProjectViewModelBase
{
public WindoTabViewModel()
{
}
private RelayCommand _newTabCommand;
public RelayCommand NewTabCommand
{
get { return _newTabCommand ?? (_newTabCommand = new RelayCommand(OnNewTab)); }
}
public void OnNewTab()
{
}
}
}