ContextMenu不是由DataTrigger设置的,但会显示它

时间:2015-10-18 08:39:37

标签: wpf mvvm triggers contextmenu

我使用MVVM模式。

有两个ViewModel: ClientViewModel DiskViewModel ,ClientViewModel有一个集合ObservableCollection<DiskViewModel>

我想展示他们的等级关系,并通过他们的ContextMenu做一些事情。我在ContextMenu TypeToBooleanConverter中通过DataTrigger设置了不同的TreeViewItem,如下所示:

<Style TargetType="{x:Type TreeViewItem}">
    <Style.Triggers>
        <DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:ClientViewModel}}">
            <Setter Property="ContextMenu">
                <Setter.Value>
                    <ContextMenu>
                        <MenuItem Header="Client"/>
                    </ContextMenu>
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

但是有一个问题:

如果我仅通过上述方法为 ClientViewModel 设置ContextMenu,而不是为 DiskViewModel 设置ContextMenu,则会显示&#34;客户机&#34;如果右键单击磁盘TreeViewItem。但我从来没有说过。

有了图片:这不是我需要的。如果我右键单击磁盘TreeViewItem,我什么都不想要。 enter image description here

上面的场景是最简单的。实际上等级关系就是:

ClientList
|---Client
    |---DiskList
        |---Disk
            |---PartitionList
                |---Partition

不同类型的项目或具有不同状态的一种类型时间具有不同的ContextMenu。列举所有案例可能是一项重要的工作。

我需要你的帮助。

代码文件:

// MainViewModel.cs
using GalaSoft.MvvmLight;
using System.Collections.ObjectModel;

namespace WpfApplication12.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            ClientList = new ObservableCollection<ClientViewModel>();
            var disk = new DiskViewModel();
            disk.Name = "disk1";
            var client = new ClientViewModel();
            client.Name = "client1";
            client.DiskList.Add(disk);
            ClientList.Add(client);
        }

        #region ClientList
        public const string ClientListPropertyName = "ClientList";
        private ObservableCollection<ClientViewModel> _clientList;
        public ObservableCollection<ClientViewModel> ClientList
        {
            get
            {
                return _clientList;
            }

            set
            {
                if (_clientList == value)
                    return;

                _clientList = value;
                RaisePropertyChanged(ClientListPropertyName);
            }
        }
        #endregion // ClientList
    }

    public class ClientViewModel : ViewModelBase
    {
        public ClientViewModel()
        {
            DiskList = new ObservableCollection<DiskViewModel>();
        }

        #region Name
        public const string NamePropertyName = "Name";
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }

            set
            {
                if (_name == value)
                    return;

                _name = value;
                RaisePropertyChanged(NamePropertyName);
            }
        }
        #endregion // Name

        #region DiskList
        public const string DiskListPropertyName = "DiskList";
        private ObservableCollection<DiskViewModel> _diskList;
        public ObservableCollection<DiskViewModel> DiskList
        {
            get
            {
                return _diskList;
            }

            set
            {
                if (_diskList == value)
                    return;

                _diskList = value;
                RaisePropertyChanged(DiskListPropertyName);
            }
        }
        #endregion // DiskList
    }

    public class DiskViewModel : ViewModelBase
    {
        public DiskViewModel()
        {

        }

        #region Name
        public const string NamePropertyName = "Name";
        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }

            set
            {
                if (_name == value)
                    return;

                _name = value;
                RaisePropertyChanged(NamePropertyName);
            }
        }
        #endregion // Name
    }
}

// MainWindow.xaml
<Window x:Class="WpfApplication12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfApplication12.ViewModel"
        xmlns:cvt="clr-namespace:InfoCore.StreamerConsole.Converters"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding Source={StaticResource Locator},Path=Main}">

    <Grid>
        <TreeView Background="AliceBlue" Margin="10"
                  ItemsSource="{Binding ClientList}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type vm:ClientViewModel}" ItemsSource="{Binding DiskList}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type vm:DiskViewModel}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.Resources>

            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Style.Triggers>
                        <DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:ClientViewModel}}">
                            <Setter Property="ContextMenu">
                                <Setter.Value>
                                    <ContextMenu>
                                        <MenuItem Header="Client"/>
                                    </ContextMenu>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>
                        <!--<DataTrigger Value="true" Binding="{Binding Converter={cvt:TypeToBooleanConverter},ConverterParameter={x:Type vm:DiskViewModel}}">
                            <Setter Property="ContextMenu">
                                <Setter.Value>
                                    <ContextMenu>
                                        <MenuItem Header="Disk"/>
                                    </ContextMenu>
                                </Setter.Value>
                            </Setter>
                        </DataTrigger>-->
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>
    </Grid>
</Window>

// ToBooleanConverter.cs
[MarkupExtensionReturnType(typeof(TypeToBooleanConverter))]
[ValueConversion(typeof(Type), typeof(bool))]
public class TypeToBooleanConverter : MarkupExtension, IValueConverter
{
    private static TypeToBooleanConverter _converter = null;

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return _converter ?? (_converter = new TypeToBooleanConverter());
    }

    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return Binding.DoNothing;

        return Type.Equals(value.GetType(), parameter);
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

0 个答案:

没有答案