Say I have an enum with four values:
public enum CompassHeading
{
North,
South,
East,
West
}
What XAML would be required to
Here is a detailed example of how to bind to enums in WPF
Assume you have the following enum
public enum EmployeeType
{
Manager,
Worker
}
You can then bind in the codebehind
typeComboBox.ItemsSource = Enum.GetValues(typeof(EmployeeType));
or use the ObjectDataProvider
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="sysEnum">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:EmployeeType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
and now you can bind in the markup
<ComboBox ItemsSource="{Binding Source={StaticResource sysEnum}}" />
Also check out: Databinding an enum property to a ComboBox in WPF
I think using an ObjectDataProvider to do that is really tedious... I have a more concise suggestion (yes I know, it's a bit late...), using a markup extension :
<ComboBox ItemsSource="{local:EnumValues local:EmployeeType}"/>
Here is the code for the markup extension :
[MarkupExtensionReturnType(typeof(object[]))]
public class EnumValuesExtension : MarkupExtension
{
public EnumValuesExtension()
{
}
public EnumValuesExtension(Type enumType)
{
this.EnumType = enumType;
}
[ConstructorArgument("enumType")]
public Type EnumType { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (this.EnumType == null)
throw new ArgumentException("The enum type is not set");
return Enum.GetValues(this.EnumType);
}
}
This may be like swearing in a church, but I'd like to declare each ComboBoxItem explicitly in the XAML for the following reasons:
C# Sample code:
public enum number { one, two, three };
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private number _number = number.one;
public number Number
{
get { return _number; }
set {
if (_number == value)
return;
_number = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Number"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
XAML code:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="480" Width="677">
<Grid>
<ComboBox SelectedValue="{Binding Number}" SelectedValuePath="Tag">
<ComboBoxItem Content="En" Tag="One"/>
<ComboBoxItem Content="To" Tag="Two"/>
<ComboBoxItem Content="Tre" Tag="Three"/>
</ComboBox>
</Grid>
As you can see, the XAML has been localized to Norwegian, without any need for changes in the C# code.
A third solution:
This is slightly more work up-front, better is easier in the long-run if you're binding to loads of Enums. Use a Converter which takes the enumeration's type as a paramter, and converts it to an array of strings as an output.
In VB.NET:
Public Class EnumToNamesConverter
Implements IValueConverter
Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Return [Enum].GetNames(DirectCast(value, Type))
End Function
Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Throw New NotImplementedException()
End Function
End Class
Or in C#:
public sealed class EnumToNamesConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum.GetNames(value.GetType());
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw New NotSupportedException()
}
}
Then in your Application.xaml
, add a global resource to access this converter:
<local:EnumToNamesConverter x:Key="EnumToNamesConverter" />
Finally use the converter in any XAML pages where you need the values of any Enum...
<ComboBox ItemsSource="{Binding
Source={x:Type local:CompassHeading},
Converter={StaticResource EnumToNamesConverter}}" />
You can use the ObjectDataProvider to do this:
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}" x:Key="odp">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:CompassHeading"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ComboBox ItemsSource="{Binding Source={StaticResource odp}}" />
I found the solution here:
http://bea.stollnitz.com/blog/?p=28
For a step-by-step walkthrough of the alternatives and derivations of technique, try this web page:
The Missing .NET #7: Displaying Enums in WPF
This article demonstrates a method of overriding the presentation of certain values as well. A good read with plenty of code samples.