来自 ItemsControl 项目的 RelayCommand 发送者

发布于 2024-09-01 00:50:09 字数 1249 浏览 2 评论 0原文

我一直在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忆沫 2024-09-08 00:50:09

如果您像在 MVVM Light 应用程序中一样使用 ViewModelLocator,则可以从 DataTemplate 中获取对 MainViewModel 的引用,

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}">

我发现这种方式比 ElementName 更清晰,但当然它假设 Main 属性在定位器中可用,并且另外 MainviewModel 被实例化为单例。显然,这并不总是可能的。在这种情况下,我认为 ElementName 解决方法是可以接受的。

在WPF中,您还可以使用Mode=FindAncestor的RelativeSource,但我发现它更混乱;)

关于“如何在视图模型中定义我的SelectDeviceCommand以便接收绑定到该项目的对象?”的问题,我不能 100% 确定我理解这个问题,但如果您想获取 DataTemplate 表示的项目(在本例中为设备),您应该使用 CommandParameter:

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}"
        CommandParameter="{Binding}"}">

干杯,
洛朗

If you use a ViewModelLocator like in MVVM Light applications, you can get a reference to the MainViewModel from within the DataTemplate with

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}">

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:

<Button Command="{Binding Main.SelectDeviceCommand, Source={StaticResource Locator}}"
        CommandParameter="{Binding}"}">

Cheers,
Laurent

笑,眼淚并存 2024-09-08 00:50:09

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

最后,我使用元素绑定回窗口(或页面)本身,因为 ViewModel 是窗口的 DataContext。首先,为您的窗口(或页面)命名:

<Window ...
    x:Name="me" />

然后直接绑定到窗口的数据上下文,如下所示:

<Button Command="{Binding DataContext.SelectDeviceCommand,ElementName=me}">

这对我有用。虽然很乱,但我认为它很可读。

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:

<Window ...
    x:Name="me" />

Then bind to the window's datacontext directly, like this:

<Button Command="{Binding DataContext.SelectDeviceCommand,ElementName=me}">

This has worked for me. It's messy, but I think it's pretty readable.

孤君无依 2024-09-08 00:50:09

我有一个 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()
        {

        }
    }
}

I have a usercontrol(x:Name="ControlClass") and it is inside a template, it doesnt work on xaml
i called it like this

<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()
        {

        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文