C# 从枚举值列表创建可检查上下文菜单的通用方法
我想创建一个上下文菜单,其中一个菜单项是一个子菜单,可以在枚举值中进行选择 我不想将枚举中的任何值硬编码到xaml中,因为我希望任何枚举值更改都能自动反映在UI中,而无需任何干预 我希望我的菜单是一个没有任何工件的常规上下文菜单(我的意思是外观应该是一个常规上下文菜单) 我尝试了很多方法,但都没有成功。我的每一次尝试都会遗漏一些东西,但主要是缺少的部分似乎是可能绑定到某个东西的转换器参数 我是红色的:C# 从枚举值列表创建可检查上下文菜单的通用方法,c#,wpf,xaml,enums,menuitem,C#,Wpf,Xaml,Enums,Menuitem,我想创建一个上下文菜单,其中一个菜单项是一个子菜单,可以在枚举值中进行选择 我不想将枚举中的任何值硬编码到xaml中,因为我希望任何枚举值更改都能自动反映在UI中,而无需任何干预 我希望我的菜单是一个没有任何工件的常规上下文菜单(我的意思是外观应该是一个常规上下文菜单) 我尝试了很多方法,但都没有成功。我的每一次尝试都会遗漏一些东西,但主要是缺少的部分似乎是可能绑定到某个东西的转换器参数 我是红色的: 这是我的许多试验和相关代码: <Window x:Class="WpfCont
<Window x:Class="WpfContextMenuWithEnum.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfContextMenuWithEnum="clr-namespace:WpfContextMenuWithEnum"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:converter="clr-namespace:WpfContextMenuWithEnum.Converter"
Title="MainWindow" Height="350" Width="525"
Name="MyWindow">
<Window.DataContext>
<wpfContextMenuWithEnum:MainWindowModel></wpfContextMenuWithEnum:MainWindowModel>
</Window.DataContext>
<Window.Resources>
<ObjectDataProvider x:Key="EnumChoiceProvider" MethodName="GetValues" ObjectType="{x:Type system:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="wpfContextMenuWithEnum:EnumChoice"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<converter:EnumToBooleanConverter x:Key="EnumToBooleanConverter"></converter:EnumToBooleanConverter>
<converter:MultiBind2ValueComparerConverter x:Key="MultiBind2ValueComparerConverter"></converter:MultiBind2ValueComparerConverter>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Text="Right click me">
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding Source={StaticResource EnumChoiceProvider}}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="True" Header="{Binding Path=.}">
<MenuItem.IsChecked>
<MultiBinding Converter="{StaticResource MultiBind2ValueComparerConverter}">
<Binding Path="DataContext.ModelEnumChoice" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" />
<Binding Path="." Mode="OneWay"></Binding>
</MultiBinding>
</MenuItem.IsChecked>
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Grid>
</Window>
试用版1:MultiBindConverter ConvertBack无法工作,它会丢失信息
<ContextMenu ItemsSource="{Binding Source={StaticResource EnumChoiceProvider}}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="True" Header="{Binding Path=.}">
<MenuItem.IsChecked>
<MultiBinding Converter="{StaticResource MultiBind2ValueComparerConverter}">
<Binding Path="DataContext.ModelEnumChoice" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" />
<Binding Path="."></Binding>
</MultiBinding>
</MenuItem.IsChecked>
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
试用2:我的转换器参数绑定根本不起作用。它从未得到任何价值
<ContextMenu ItemsSource="{Binding Source={StaticResource EnumChoiceProvider}}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="True" Header="{Binding Path=.}">
<MenuItem.IsChecked>
<Binding Path="DataContext.ModelEnumChoice" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}">
<Binding.Converter>
<converter:ConverterWrapperWithDependencyParameterConverter Converter="{StaticResource EnumToBooleanConverter}"
Parameter="{Binding Path=.}"/>
</Binding.Converter>
</Binding>
</MenuItem.IsChecked>
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
试验3:
使用template和SelectedItem创建列表框,但UI并不像应有的那样标准(会出现一个额外的框架)。因此您希望能够
- 将任何
绑定到Enum
并显示其ContextMenu
属性Description
- 在所选的
前面有一个复选标记,在任何给定时间只有一个可以“激活”枚举
- 将所选值存储在ViewModel中,并在选择更改时执行某些逻辑
main window.xaml
<Window x:Class="WpfApplication1.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:WpfApplication1.ViewModel"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow"
Height="300"
Width="250">
<!-- Set data context -->
<Window.DataContext>
<viewModel:MainViewModel />
</Window.DataContext>
<!-- Converters -->
<Window.Resources>
<local:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
<local:EnumCheckedConverter x:Key="EnumCheckedConverter" />
</Window.Resources>
<!-- Element -->
<TextBox Text="Right click me">
<!-- Context menu -->
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding EnumChoiceProvider}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<!-- Menu item header bound to enum converter -->
<!-- IsChecked bound to current selection -->
<!-- Toggle bound to a command, setting current selection -->
<MenuItem
IsCheckable="True"
Width="150"
Header="{Binding Path=., Converter={StaticResource EnumDescriptionConverter}}"
Command="{Binding DataContext.ToggleEnumChoiceCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"
CommandParameter="{Binding}">
<MenuItem.IsChecked>
<MultiBinding Mode="OneWay"
NotifyOnSourceUpdated="True"
UpdateSourceTrigger="PropertyChanged"
Converter="{StaticResource EnumCheckedConverter}">
<Binding Path="DataContext.SelectedEnumChoice"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}" />
<Binding Path="."></Binding>
</MultiBinding>
</MenuItem.IsChecked>
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Window>
EnumCheckedConverter.cs
namespace WpfApplication1.ViewModel
{
public class MainViewModel : ViewModelBase // where base implements INotifyPropertyChanged
{
private EnumChoice? _selectedEnumChoice;
public MainViewModel()
{
EnumChoiceProvider = new ObservableCollection<EnumChoice>
(Enum.GetValues(typeof(EnumChoice)).Cast<EnumChoice>());
ToggleEnumChoiceCommand = new RelayCommand<EnumChoice>
(arg => SelectedEnumChoice = arg);
}
// Selections
public ObservableCollection<EnumChoice> EnumChoiceProvider { get; set; }
// Current selection
public EnumChoice? SelectedEnumChoice
{
get
{
return _selectedEnumChoice;
}
set
{
_selectedEnumChoice = value != _selectedEnumChoice ? value : null;
RaisePropertyChanged();
}
}
// "Selection changed" command
public ICommand ToggleEnumChoiceCommand { get; private set; }
}
}
namespace WpfApplication1
{
public enum EnumChoice
{
[Description("Default")]
ChoiceDefault,
[Description("<1>")]
Choice1,
[Description("<2>")]
Choice2
}
}
namespace WpfApplication1
{
// Extract enum description
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
MemberInfo[] memberInfos = value.GetType().GetMember(value.ToString());
if (memberInfos.Length > 0)
{
object[] attrs = memberInfos[0].GetCustomAttributes(typeof (DescriptionAttribute), false);
if (attrs.Length > 0)
return ((DescriptionAttribute) attrs[0]).Description;
}
return value;
// or maybe just
//throw new InvalidEnumArgumentException(string.Format("no description found for enum {0}", value));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
namespace WpfApplication1
{
// Check if currently selected
public class EnumCheckedConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return !values.Contains(null) && values[0].ToString().Equals(values[1].ToString(), StringComparison.OrdinalIgnoreCase);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
我添加我的解决方案作为参考。两种解决方案(已接受的答案和我的答案都很好)。我在等待一个有效的完整答案的同时创建了一个。我认为Mikko有一种更标准的工作方式,并且可能更容易维护。Mikko解决方案还展示了一些WPF技巧(Relaycommand、MultiBinding等)的良好用法 我的解决方案的主要优点是通过使用通用代码来抽象“复杂性”,该代码模拟表示每个枚举值及其属性(IsChecked、Name、DisplayName)的项集合。所有这些都是隐藏的,不需要模型中的任何内容。 但不管怎样,就像其他信息一样
<Window x:Class="WpfContextMenuWithEnum.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfContextMenuWithEnum="clr-namespace:WpfContextMenuWithEnum"
Title="MainWindow" Height="350" Width="525"
Name="MyWindow">
<Window.DataContext>
<wpfContextMenuWithEnum:MainWindowModel></wpfContextMenuWithEnum:MainWindowModel>
</Window.DataContext>
<Window.Resources>
<wpfContextMenuWithEnum:EnumWrapperIteratorAndSelector x:Key="EnumWrapperIteratorAndSelector"
Enum="{Binding DataContext.SelectedEnumChoice, Mode=TwoWay, ElementName=MyWindow}" />
</Window.Resources>
<Grid>
<TextBox Text="Right click me">
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding Source={StaticResource EnumWrapperIteratorAndSelector}}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="True" Header="{Binding DisplayName}" IsChecked="{Binding IsChecked}">
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Grid>
</Window>
可以在任何地方使用的泛型类:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
namespace WpfContextMenuWithEnum
{
/// <summary>
/// Note: Freezable is necessary otherwise binding will never occurs if EnumWrapperIteratorAndSelector is defined
/// as resources. See article for more info:
/// http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
/// </summary>
public class EnumWrapperIteratorAndSelector : Freezable, IEnumerable<EnumWrapperIteratorAndSelectorChoice>, INotifyCollectionChanged
{
// ******************************************************************
public static readonly DependencyProperty EnumProperty =
DependencyProperty.Register("Enum", typeof(Enum), typeof(EnumWrapperIteratorAndSelector), new PropertyMetadata(null, PropertyChangedCallback));
ObservableCollection<EnumWrapperIteratorAndSelectorChoice> _allEnumValue = new ObservableCollection<EnumWrapperIteratorAndSelectorChoice>();
// ******************************************************************
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (!(dependencyPropertyChangedEventArgs.NewValue is Enum))
{
throw new ArgumentException("Only enum are supported.");
}
var me = dependencyObject as EnumWrapperIteratorAndSelector;
if (me != null)
{
if (dependencyPropertyChangedEventArgs.OldValue == null)
{
me.ResetWithNewEnum(dependencyPropertyChangedEventArgs.NewValue);
}
else
{
foreach(EnumWrapperIteratorAndSelectorChoice enumWrapperIteratorAndSelectorChoice in me._allEnumValue)
{
enumWrapperIteratorAndSelectorChoice.RaiseChangeIfAppropriate(dependencyPropertyChangedEventArgs);
}
}
}
}
// ******************************************************************
private void ResetWithNewEnum(object enumValue)
{
_allEnumValue.Clear();
var enumType = Enum.GetType();
foreach (Enum enumValueIter in Enum.GetValues(enumValue.GetType()))
{
MemberInfo[] memberInfos = enumType.GetMember(enumValueIter.ToString());
if (memberInfos.Length > 0)
{
var desc = memberInfos[0].GetCustomAttribute<DescriptionAttribute>();
if (desc != null)
{
_allEnumValue.Add(new EnumWrapperIteratorAndSelectorChoice(this, enumValueIter, desc.Description));
}
else
{
_allEnumValue.Add(new EnumWrapperIteratorAndSelectorChoice(this, enumValueIter));
}
}
}
}
// ******************************************************************
public Enum Enum
{
get { return (Enum)GetValue(EnumProperty); }
set
{
SetValue(EnumProperty, value);
}
}
// ******************************************************************
internal void SetCurrentValue(Enum enumValue)
{
SetCurrentValue(EnumProperty, enumValue);
}
// ******************************************************************
public IEnumerator GetEnumerator()
{
return _allEnumValue.GetEnumerator();
}
// ******************************************************************
IEnumerator<EnumWrapperIteratorAndSelectorChoice> IEnumerable<EnumWrapperIteratorAndSelectorChoice>.GetEnumerator()
{
return _allEnumValue.GetEnumerator();
}
// ******************************************************************
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add { _allEnumValue.CollectionChanged += value; }
remove { _allEnumValue.CollectionChanged -= value; }
}
// ******************************************************************
protected override Freezable CreateInstanceCore()
{
return new EnumWrapperIteratorAndSelector();
}
// ******************************************************************
}
}
using System;
using System.ComponentModel;
using System.Windows;
namespace WpfContextMenuWithEnum
{
public class EnumWrapperIteratorAndSelectorChoice : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private EnumWrapperIteratorAndSelector _enumWrapperIteratorAndSelector;
public Enum EnumValueRef { get; private set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsChecked
{
get
{
return _enumWrapperIteratorAndSelector.Enum.Equals(EnumValueRef);
}
set
{
if (value) // Can only set value
{
_enumWrapperIteratorAndSelector.SetCurrentValue(EnumValueRef);
}
}
}
internal void RaiseChangeIfAppropriate(DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (EnumValueRef.Equals(dependencyPropertyChangedEventArgs.OldValue) ||
EnumValueRef.Equals(dependencyPropertyChangedEventArgs.NewValue))
{
var propertyChangeLocal = PropertyChanged;
if (propertyChangeLocal != null)
{
propertyChangeLocal(this, new PropertyChangedEventArgs("IsChecked"));
}
}
}
public EnumWrapperIteratorAndSelectorChoice(EnumWrapperIteratorAndSelector enumWrapperIteratorAndSelector,
Enum enumValueRef, string description = null)
{
_enumWrapperIteratorAndSelector = enumWrapperIteratorAndSelector;
EnumValueRef = enumValueRef;
Name = enumValueRef.ToString();
Description = description;
}
public string DisplayName
{
get { return Description ?? Name; }
}
}
}
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
namespace WpfContextMenuWithEnum
{
public class MainWindowModel : ViewModelBase
{
private EnumChoice _selectedEnumChoice;
public EnumChoice SelectedEnumChoice
{
get { return _selectedEnumChoice; }
set { _selectedEnumChoice = value; RaisePropertyChanged(); }
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Collections.Specialized;
使用系统组件模型;
运用系统反思;
使用System.Windows;
命名空间WpfContextMenuWithEnum
{
///
///注意:如果定义了EnumWrapperIteratorAndSelector,则Freezable是必需的,否则将永远不会发生绑定
///作为参考资料。有关更多信息,请参阅文章:
/// http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
///
公共类EnumWrapperIteratorAndSelector:Freezable、IEnumerable、INotifyCollectionChanged
{
// ******************************************************************
公共静态只读DependencyProperty EnumProperty=
Register(“Enum”、typeof(Enum)、typeof(EnumWrapperIteratorAndSelector)、newPropertyMetadata(null、PropertyChangedCallback));
ObservableCollection_allEnumValue=新的ObservableCollection();
// ******************************************************************
私有静态无效属性ChangedCallback(DependencyObject DependencyObject,DependencyPropertyChangedEventArgs DependencyPropertyChangedEventArgs)
{
如果(!(dependencyPropertyChangedEventArgs.NewValue为枚举))
{
抛出新ArgumentException(“仅支持枚举”);
}
var me=作为EnumWrapperIterator和Selector的dependencyObject;
如果(me!=null)
{
if(dependencPropertyChangedEventArgs.OldValue==null)
{
me.ResetWithNewEnum(dependencPropertyChangedEventArgs.NewValue);
}
其他的
{
foreach(EnumWrapperIterator和SelectorChoice EnumWrapperIterator和SelectorChoice in me.\u allEnumValue)
{
EnumWrapperIterator和SelectorChoice.RaiseChangeIf适当(dependencyPropertyChangedEventArgs);
}
}
}
}
// ******************************************************************
私有void ResetWithNewEnum(对象枚举值)
{
_allEnumValue.Clear();
var enumType=Enum.GetType();
foreach(枚举)
<Window x:Class="WpfContextMenuWithEnum.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfContextMenuWithEnum="clr-namespace:WpfContextMenuWithEnum"
Title="MainWindow" Height="350" Width="525"
Name="MyWindow">
<Window.DataContext>
<wpfContextMenuWithEnum:MainWindowModel></wpfContextMenuWithEnum:MainWindowModel>
</Window.DataContext>
<Window.Resources>
<wpfContextMenuWithEnum:EnumWrapperIteratorAndSelector x:Key="EnumWrapperIteratorAndSelector"
Enum="{Binding DataContext.SelectedEnumChoice, Mode=TwoWay, ElementName=MyWindow}" />
</Window.Resources>
<Grid>
<TextBox Text="Right click me">
<TextBox.ContextMenu>
<ContextMenu ItemsSource="{Binding Source={StaticResource EnumWrapperIteratorAndSelector}}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<MenuItem IsCheckable="True" Header="{Binding DisplayName}" IsChecked="{Binding IsChecked}">
</MenuItem>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</Grid>
</Window>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
namespace WpfContextMenuWithEnum
{
/// <summary>
/// Note: Freezable is necessary otherwise binding will never occurs if EnumWrapperIteratorAndSelector is defined
/// as resources. See article for more info:
/// http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
/// </summary>
public class EnumWrapperIteratorAndSelector : Freezable, IEnumerable<EnumWrapperIteratorAndSelectorChoice>, INotifyCollectionChanged
{
// ******************************************************************
public static readonly DependencyProperty EnumProperty =
DependencyProperty.Register("Enum", typeof(Enum), typeof(EnumWrapperIteratorAndSelector), new PropertyMetadata(null, PropertyChangedCallback));
ObservableCollection<EnumWrapperIteratorAndSelectorChoice> _allEnumValue = new ObservableCollection<EnumWrapperIteratorAndSelectorChoice>();
// ******************************************************************
private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (!(dependencyPropertyChangedEventArgs.NewValue is Enum))
{
throw new ArgumentException("Only enum are supported.");
}
var me = dependencyObject as EnumWrapperIteratorAndSelector;
if (me != null)
{
if (dependencyPropertyChangedEventArgs.OldValue == null)
{
me.ResetWithNewEnum(dependencyPropertyChangedEventArgs.NewValue);
}
else
{
foreach(EnumWrapperIteratorAndSelectorChoice enumWrapperIteratorAndSelectorChoice in me._allEnumValue)
{
enumWrapperIteratorAndSelectorChoice.RaiseChangeIfAppropriate(dependencyPropertyChangedEventArgs);
}
}
}
}
// ******************************************************************
private void ResetWithNewEnum(object enumValue)
{
_allEnumValue.Clear();
var enumType = Enum.GetType();
foreach (Enum enumValueIter in Enum.GetValues(enumValue.GetType()))
{
MemberInfo[] memberInfos = enumType.GetMember(enumValueIter.ToString());
if (memberInfos.Length > 0)
{
var desc = memberInfos[0].GetCustomAttribute<DescriptionAttribute>();
if (desc != null)
{
_allEnumValue.Add(new EnumWrapperIteratorAndSelectorChoice(this, enumValueIter, desc.Description));
}
else
{
_allEnumValue.Add(new EnumWrapperIteratorAndSelectorChoice(this, enumValueIter));
}
}
}
}
// ******************************************************************
public Enum Enum
{
get { return (Enum)GetValue(EnumProperty); }
set
{
SetValue(EnumProperty, value);
}
}
// ******************************************************************
internal void SetCurrentValue(Enum enumValue)
{
SetCurrentValue(EnumProperty, enumValue);
}
// ******************************************************************
public IEnumerator GetEnumerator()
{
return _allEnumValue.GetEnumerator();
}
// ******************************************************************
IEnumerator<EnumWrapperIteratorAndSelectorChoice> IEnumerable<EnumWrapperIteratorAndSelectorChoice>.GetEnumerator()
{
return _allEnumValue.GetEnumerator();
}
// ******************************************************************
public event NotifyCollectionChangedEventHandler CollectionChanged
{
add { _allEnumValue.CollectionChanged += value; }
remove { _allEnumValue.CollectionChanged -= value; }
}
// ******************************************************************
protected override Freezable CreateInstanceCore()
{
return new EnumWrapperIteratorAndSelector();
}
// ******************************************************************
}
}
using System;
using System.ComponentModel;
using System.Windows;
namespace WpfContextMenuWithEnum
{
public class EnumWrapperIteratorAndSelectorChoice : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private EnumWrapperIteratorAndSelector _enumWrapperIteratorAndSelector;
public Enum EnumValueRef { get; private set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsChecked
{
get
{
return _enumWrapperIteratorAndSelector.Enum.Equals(EnumValueRef);
}
set
{
if (value) // Can only set value
{
_enumWrapperIteratorAndSelector.SetCurrentValue(EnumValueRef);
}
}
}
internal void RaiseChangeIfAppropriate(DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
if (EnumValueRef.Equals(dependencyPropertyChangedEventArgs.OldValue) ||
EnumValueRef.Equals(dependencyPropertyChangedEventArgs.NewValue))
{
var propertyChangeLocal = PropertyChanged;
if (propertyChangeLocal != null)
{
propertyChangeLocal(this, new PropertyChangedEventArgs("IsChecked"));
}
}
}
public EnumWrapperIteratorAndSelectorChoice(EnumWrapperIteratorAndSelector enumWrapperIteratorAndSelector,
Enum enumValueRef, string description = null)
{
_enumWrapperIteratorAndSelector = enumWrapperIteratorAndSelector;
EnumValueRef = enumValueRef;
Name = enumValueRef.ToString();
Description = description;
}
public string DisplayName
{
get { return Description ?? Name; }
}
}
}
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
namespace WpfContextMenuWithEnum
{
public class MainWindowModel : ViewModelBase
{
private EnumChoice _selectedEnumChoice;
public EnumChoice SelectedEnumChoice
{
get { return _selectedEnumChoice; }
set { _selectedEnumChoice = value; RaisePropertyChanged(); }
}
}
}