来自ItemsControl项的RelayCommand发件人

时间:2010-05-11 01:46:05

标签: c# wpf mvvm 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,这是正确的吗?)

3 个答案:

答案 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)

是的,我已经击中了这一个。我看到有些人使用自定义的“CommandReference”类来解决它,他们将这些类作为资源添加到窗口中,但我无法使其工作。

最后,我使用元素绑定回到窗口(或页面)本身,因为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()
        {

        }
    }
}