【发布时间】:2011-11-21 05:31:49
【问题描述】:
我的模型使用枚举进行固定的多项选择。我正在使用位于 http://deanchalk.me.uk/post/Enumeration-Binding-In-Silverlight.aspx 的 Dean Chalk 的 EnumBinder 绑定到组合框。除了未显示默认值外,一切似乎都很好。选择的索引是-1,我绑定到SelectedItem还是SelectedValue都没关系。否则,组合框工作正常。我对任何其他绑定组合框的默认值都没有问题。
枚举绑定支持.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);
}
}
}
枚举值转换器.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 sn-p:
<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");
}
}
}
【问题讨论】:
-
首选项类是什么样的?
-
这只是我的模型中包含的一个POCO类,它是一个属性包并实现了INotifyPropertyChanged。我在模型中有一个类的实例,它是一个单独的类,因此我可以轻松地将其序列化到存储中。
-
好的,您至少可以发布 Preferences.SortOrder 代码吗?
-
public PeopleSortOptionsEnum SortOrder { get { return sortOrder; } set { if (sortOrder != value) { sortOrder = value; PropertyHasChanged("排序顺序"); } } }
-
这只是一个标准属性。就像我之前说的,我对任何其他属性都没有问题,而且我很确定这是上面发布的代码或 SL 组合框的问题。
标签: silverlight xaml binding combobox enums