在ItemsControl中的ContextMenu时绑定到两个不同的级别

时间:2014-09-23 13:48:40

标签: c# wpf mvvm .net-3.5

我需要将CommandCommandParameter绑定到位于ContextMenu内的WPF MenuItem ItemsControl.ItemTemplate内的两个不同的类。问题是ContextMenu有一个单独的可视树而不是窗口的其余部分。我在.NET 4.0+中使用它,但无法找到适用于.NET 3.5的解决方法。

注意:即使是运行中的.NET 4.0+解决方法也可以在运行时运行,但会破坏Visual Studio 2013 Designer和Blend Designer。

如何将CommandParameter绑定到单个CustomerViewModel并将Command绑定到.NET 3.5中的EditCustomersController

查看

<Window
    x:Class="MvvmLight1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MVVM Light Application"
    DataContext="{Binding EditCustomers, Source={StaticResource Locator}}">

    <ItemsControl
        x:Name="rootElement"
        ItemsSource="{Binding Customers}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock
                    Text="{Binding Name}">
                    <TextBlock.ContextMenu>
                        <ContextMenu
                            PlacementTarget="{Binding ElementName=myTextBlock}">
                            <MenuItem
                                Header="Capitalize Using RelativeSource (Does not work)"
                                CommandParameter="{Binding}"
                                Command="{Binding
                                    Path=DataContext.CapitalizeCommand,
                                    RelativeSource={RelativeSource
                                        FindAncestor,
                                        AncestorType={x:Type Window}}}" />
                            <MenuItem
                                Header="Lowercase Using RelativeSource (Does not work)"
                                CommandParameter="{Binding}"
                                Command="{Binding
                                    Path=DataContext.LowercaseCommand,
                                    RelativeSource={RelativeSource
                                        FindAncestor,
                                        AncestorType={x:Type Window}}}" />
                            <MenuItem
                                Header="Capitalize Using Source (Only works in .NET 4.0+)"
                                CommandParameter="{Binding}"
                                Command="{Binding
                                    Path=DataContext.CapitalizeCommand,
                                    Source={x:Reference Name=rootElement}}" />
                            <MenuItem
                                Header="Lowercase Using Source (Only works in .NET 4.0+)"
                                CommandParameter="{Binding}"
                                Command="{Binding
                                    Path=DataContext.LowercaseCommand,
                                    Source={x:Reference Name=rootElement}}" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                </TextBlock>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

控制器

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Collections.Generic;
using System.Windows.Input;

public class EditCustomersController : ViewModelBase
{
    public EditCustomersController()
    {
        this.CapitalizeCommand = new RelayCommand<CustomerViewModel>(this.Capitalize);
        this.LowercaseCommand = new RelayCommand<CustomerViewModel>(this.Lowercase);

        var c = new List<CustomerViewModel>();
        c.Add(new CustomerViewModel("Fred"));
        c.Add(new CustomerViewModel("Bob"));
        c.Add(new CustomerViewModel("Sue"));
        c.Add(new CustomerViewModel("Sally"));
        this.Customers = c;
    }

    public IEnumerable<CustomerViewModel> Customers { get; set; }

    public ICommand CapitalizeCommand { get; private set; }

    public ICommand LowercaseCommand { get; private set; }

    private void Capitalize(CustomerViewModel customer)
    {
        customer.Name = customer.Name.ToUpper();
    }

    private void Lowercase(CustomerViewModel customer)
    {
        customer.Name = customer.Name.ToLower();
    }
}

视图模型

using GalaSoft.MvvmLight;

public class CustomerViewModel : ViewModelBase
{
    private string name;

    public CustomerViewModel(string name)
    {
        this.name = name;
    }

    public string Name
    {
        get
        {
            return this.name;
        }

        set
        {
            this.Set(() => this.Name, ref this.name, value);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

通过将ContextMenu移动到资源并通过使用DataContext属性传递顶级Tag,使其适用于所有.NET版本。在ContextMenu MenuItem内,我可以使用CustomerViewModel{Binding}使用EditCustomersController和{{1}的绑定访问当前Tag }}

查看

RelativeSource