我的模型使用枚举进行固定的多项选择。我在http://deanchalk.me.uk/post/Enumeration-Binding-In-Silverlight.aspx使用Dean Chalk的EnumBinder绑定到一个组合框。除了未显示默认值外,一切似乎都很好用。所选索引为-1,如果我绑定到SelectedItem或SelectedValue则无关紧要。组合框效果很好。我对使用任何其他绑定组合框的默认值没有任何问题。
enumbindingsupport.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
/* All of this was once just part of the RichClient sub-namespace
* but it has its uses elsewhere, so it has been moved.
*/
/// <summary>
/// Container for enumeration values.
/// </summary>
/// <remarks>
/// http://deanchalk.me.uk/post/Enumeration-Binding-In-Silverlight.aspx
/// </remarks>
public sealed class EnumContainer
{
public int EnumValue { get; set; }
public string EnumDescription { get; set; }
public object EnumOriginalValue { get; set; }
public override string ToString() {
return EnumDescription;
}
public override bool Equals(object obj) {
if (obj == null)
return false;
if (obj is EnumContainer)
return EnumValue.Equals((int)((EnumContainer)obj).EnumValue);
return EnumValue.Equals((int)obj);
}
public override int GetHashCode() {
return EnumValue.GetHashCode();
}
}
/// <summary>
/// A collection to store a list of EnumContainers that hold enum values.
/// </summary>
/// <remarks>
/// http://deanchalk.me.uk/post/Enumeration-Binding-In-Silverlight.aspx
/// </remarks>
/// <typeparam name="T"></typeparam>
public class EnumCollection<T> : List<EnumContainer> where T : struct
{
public EnumCollection() {
var type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("This class only supports Enum types");
var fields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public);
foreach (var field in fields) {
var container = new EnumContainer();
container.EnumOriginalValue = field.GetValue(null);
container.EnumValue = (int)field.GetValue(null);
container.EnumDescription = field.Name;
var atts = field.GetCustomAttributes(false);
foreach (var att in atts)
if (att is DescriptionAttribute) {
container.EnumDescription = ((DescriptionAttribute)att).Description;
break;
}
Add(container);
}
}
}
enumvalueconverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
/// <summary>
/// Supports two-way binding of enumerations.
/// </summary>
public class EnumValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture) {
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture) {
if (value == null)
return null;
if (value.GetType() == targetType)
return value;
return ((EnumContainer)value).EnumOriginalValue;
}
}
使用的枚举:
/// <summary>
/// Describes the available sorting options.
/// </summary>
public enum PeopleSortOptionsEnum
{
[Display(Order = 10)]
[Description("First Name, Last Name")]
FirstNameThenLastName,
[Display(Order = 20)]
[Description("Last Name, First Name")]
LastNameThenFirstName,
[Display(Order = 30)]
Grade,
[Display(Order = 40)]
Gender,
[Display(Order = 50)]
Age
}
我模特的属性:
/// <summary>
/// This is the list for the enumeration to bind to.
/// </summary>
public EnumCollection<PeopleSortOptionsEnum> AvailableSortOptions
{
get { return new EnumCollection<PeopleSortOptionsEnum>(); }
}
XAML片段:
<ComboBox ItemsSource="{Binding Path=AvailableSortOptions, Mode=OneWay}" SelectedValue="{Binding Path=Preferences.SortOrder, Mode=TwoWay, Converter={StaticResource EnumConverter}}" Grid.Column="1" Grid.Row="2" Height="32" Margin="48,31,0,0" x:Name="cboSort" VerticalAlignment="Top" />
如果Preferences.SortOrder的类型为PeopleSortOptionsEnum,则转换器在我的app.xaml中作为所有枚举类型的转换器。
任何人都知道为什么它不会将索引设置为当前选定的值?我即将在代码隐藏中抛出一些代码,将selectedindex设置为加载时当前选择的值,但考虑到它,我觉得很脏。
除了这个问题,它的效果非常好,所以感谢Dean!
修改添加Preferences.SortOrder代码:
public PeopleSortOptionsEnum SortOrder
{
get { return sortOrder; }
set
{
if (sortOrder != value)
{
sortOrder = value;
PropertyHasChanged("SortOrder");
}
}
}
答案 0 :(得分:0)
问题是你的枚举转换器类上的Convert方法:
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture) {
return (int)value;
}
当组合框SelectedItem从SortOrder获取值时,它返回Enum值,该转换器将转换为int。但是,组合框项是EnumContainer对象的集合,而不是整数。因此无法设置所选项目。
要解决此问题,您必须做两件事。首先更改组合框绑定并设置SelectedValuePath:
<ComboBox ItemsSource="{Binding Path=AvailableSortOptions}"
SelectedValue="{Binding Path=SortOrder, Mode=TwoWay, Converter={StaticResource EnumConverter}}"
SelectedValuePath="EnumOriginalValue"/>
其次,您必须稍微修改转换器上的Convert方法:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
一旦我做了这两个更改,它就开始按预期工作了。