Мои модели используют перечисления для фиксированного множественного выбора.Я использую EnumBinder Дина Чела, найденный в http://deanchalk.me.uk/post/Enumeration-Binding-In-Silverlight.aspx, для привязки к комбинированному списку.Кажется, все работает отлично, кроме значения по умолчанию не отображается.Выбранный индекс равен -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 на текущее выбранное значение при загрузке, но я чувствую себя таким грязным, просто думая об этом.
Помимо этой проблемы, это работает чудесно, так что спасибоДин!
Редактировать Добавление кода Preferences.SortOrder:
public PeopleSortOptionsEnum SortOrder
{
get { return sortOrder; }
set
{
if (sortOrder != value)
{
sortOrder = value;
PropertyHasChanged("SortOrder");
}
}
}