[虽然已经回答了,但我想展示一种“XAML 友好”的方式]
在数据上下文中使用集合会导致需要选择相同enum
值的每个视图模型的复制代码,即,如果您有多个视图模型保存Person
要编辑的对象 - 每个视图模型都需要定义、初始化和填充收藏。或者,需要更改继承拓扑。
让我们定义Gender
和Person
:
public enum Gender
{
Female,
Male,
Unspecified
}
public class Person : INotifyPropertyChanged
{
private Gender _gender = Gender.Unspecified;
public Gender Gender
{
get { return _gender; }
set
{
if (value == _gender) return;
_gender = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
我已经定义了 person in 的一个属性MainWindow
以避免这个例子的 MVVM 开销,但是如果有一个持有该Person
属性的视图模型(只有DockPanel
在 xaml 文件中不会有数据上下文的设置器),它将非常相似)
public partial class MainWindow
{
#region ActivePerson
/// <summary>
/// Gets or sets an instance of <see cref="Person"/> object to use for testing.
/// </summary>
public Person ActivePerson
{
get { return (Person) GetValue(ActivePersonProperty); }
set { SetValue(ActivePersonProperty, value); }
}
/// <summary>
/// Identifies the <see cref="ActivePerson"/> property.
/// </summary>
public static readonly DependencyProperty ActivePersonProperty =
DependencyProperty.Register("ActivePerson", typeof (Person), typeof (MainWindow), new UIPropertyMetadata(null));
#endregion
public MainWindow()
{
ActivePerson = new Person();
InitializeComponent();
}
}
由于Enum
不是 aIEnumerable
组合框期望的 a ItemsSource
,我们需要一些可以采用 aEnum
并枚举所有可用值的东西。这是通过ObjectDataProvider
声明为资源的 - 在本例中为 App.xaml,但可以是加载的任何资源字典的一部分,因此组合可以进入其范围(当然,Window.Resources
或者UserControl.Resorces
是有效的选项)
<Application x:Class="EnimObjectProvider.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:enumObjectProvider="clr-namespace:EnumObjectProvider"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ObjectDataProvider x:Key="Genders"
ObjectType="{x:Type system:Enum}"
MethodName="GetValues">
<ObjectDataProvider.MethodParameters>
<system:Type>enumObjectProvider:Gender</system:Type>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Application.Resources>
</Application>
现在 in 的使用MainWindow
很简单:
<Window x:Class="EnimObjectProvider.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<DockPanel DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
Margin="20">
<ComboBox DockPanel.Dock="Top"
ItemsSource="{Binding Source={StaticResource Genders}}"
SelectedItem="{Binding ActivePerson.Gender}" />
<!--This text block is for testing of the Gender property of ActivePerson-->
<TextBlock Text="{Binding ActivePerson.Gender, StringFormat='Current gender is: {0}'}"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</DockPanel>
</Window>
这样,我们在ObjectDataProvider
每个应用程序和任何我们想要使用组合、列表框或任何项目控件的地方声明唯一一次来列出这个枚举的可用值,我们可以对ItemsSource
属性进行相同的绑定。