![](/img/trans.png)
[英]How to get the value of a selected item in a combobox in a datagridview
[英]Binding combobox with an Enumeration value and get the selected item in the form of enum
我有一个枚举:
public enum InspectionCardsGroupOption
{
Application = 0,
ApplicationType,
InspectionStation,
ComponentSide
};
现在我正在使用 wpf MVVM 设计模式。 此枚举在 ViewModel 中。 我在 xaml 中有一个 ComboBox。 我需要将该 ComboBox 绑定到这个枚举,并且在 ComboBox 的选择更改时,它应该以枚举值的形式给我枚举值。
平台:windows10,语言:C# 我是编程新手,所以如果有人能给我详细的解释,那对我会有帮助。
首先在 xaml 中创建一个 ObjectDataProvider,如下所示在 Resource 标签内:
<ObjectDataProvider x:Key="odpEnum"
MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:Comparators"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:EnumDescriptionConverter x:Key="enumDescriptionConverter"></local:EnumDescriptionConverter>
现在在上面的代码示例中,sys:Enum 有一个别名 sys,它来自命名空间 xmlns:sys="clr-namespace:System;assembly=mscorlib"。 所以需要添加这个。
添加一个组合框,如下所示:
<ComboBox Grid.Row="1" Grid.Column="1" Height="25" Width="100" Margin="5"
ItemsSource="{Binding Source={StaticResource odpEnum}}"
SelectedItem="{Binding Path=MySelectedItem}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
让我考虑您有一个枚举类型,如下所示:
public enum Comparators
{
[Description("Application")]
Application,
[Description("Application Type")]
ApplicationType,
[Description("Inspection Name")]
InspectionName,
[Description("Component Type")]
ComponentType
}
所以将它保存在 viewmodel 部分(在视图模型之外,但在与视图模型相同的命名空间内)
现在在 viewmodel 中创建一个属性,如下所示从 XAML ComboBox 中获取 selectedItem
private Comparators _MySelectedItem;
public Comparators MySelectedItem
{
get { return _MySelectedItem; }
set
{
_MySelectedItem = value;
OnPropertyChanged("MySelectedItem");
}
}
创建一个转换器类,如下所示:--
public class EnumDescriptionConverter : IValueConverter
{
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
{
return enumObj.ToString();
}
else
{
DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
return attrib.Description;
}
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Comparators)value;
string description = GetEnumDescription(myEnum);
return description;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
当您运行此示例时,您会发现您将在 _MySelectedItem = value 中获得 selectedItem 作为枚举类型; 在视图模型的属性中。
这可以通过 MVVM 纯粹的方式通过几个辅助类来实现。
myValueDisplayPair.cs
/// <summary>
/// Equivalent to KeyValuePair<object, string> but with more memorable property names for use with ComboBox controls
/// </summary>
/// <remarks>
/// Bind ItemsSource to IEnumerable<ValueDisplayPair>, set DisplayMemberPath = Display, SelectedValuePath = Value, bind to SelectedValue
/// </remarks>
public abstract class myValueDisplayPair
{
public object Value { get; protected set; }
public string Display { get; protected set; }
}
/// <summary>
/// Equivalent to KeyValuePair<T, string>
/// </summary>
/// <typeparam name="T"></typeparam>
public class myValueDisplayPair<T> : myValueDisplayPair
{
internal perValueDisplayPair(T value, string display)
{
Value = value;
Display = display;
}
public new T Value { get; }
public override string ToString() => $"Display: {Display} Value: {Value}";
}
myEnumHelper.cs
/// <summary>
/// Helper class for enum types
/// </summary>
public static class myEnumExtender
{
/// <summary>
/// Get the value of a Description attribute assigned to an enum element
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string Description(this Enum value)
{
var fieldInfo = value
.GetType()
.GetField(value.ToString());
var attributes = fieldInfo
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.OfType<DescriptionAttribute>()
.ToList();
return attributes.Any() ? attributes.First().Description : value.ToString();
}
/// <summary>
/// Gets all the elements of an enum type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// c# doesn't support where T: Enum - this is the best compromise
/// </remarks>
public static ReadOnlyCollection<T> GetValues<T>()
where T : struct, IComparable, IFormattable, IConvertible
{
var itemType = typeof (T);
if (!itemType.IsEnum)
throw new ArgumentException($"Type '{itemType.Name}' is not an enum");
var fields = itemType
.GetFields()
.Where(field => field.IsLiteral);
return fields
.Select(field => field.GetValue(itemType))
.Cast<T>()
.ToList()
.AsReadOnly();
}
/// <summary>
/// Generate a <see cref="myValueDisplayPair"/> list containing all elements of an enum type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sortByDisplay"></param>
public static ReadOnlyCollection<myValueDisplayPair<T>> MakeValueDisplayPairs<T>(bool sortByDisplay = false)
where T : struct, IComparable, IFormattable, IConvertible
{
var itemType = typeof(T);
if (!itemType.IsEnum)
throw new ArgumentException($"Type '{itemType.Name}' is not an enum");
var values = GetValues<T>();
var result = values
.Select(v => v.CreateValueDisplayPair())
.ToList();
if (sortByDisplay)
result.Sort((p1, p2) => string.Compare(p1.Display, p2.Display, StringComparison.InvariantCultureIgnoreCase));
return result.AsReadOnly();
}
}
这些可以在您的 ViewModel 中使用
public ReadOnlyCollection<lcValueDisplayPair<InspectionCardsGroupOption>> AllInspectionCardsGroupOptions { get; }
= myEnumExtender.MakeValueDisplayPairs<InspectionCardsGroupOption>();
private InspectionCardsGroupOption _selectedInspectionCardsGroupOption;
public InspectionCardsGroupOption SelectedInspectionCardsGroupOption
{
get => _selectedInspectionCardsGroupOption;
set => Set(nameof(SelectedInspectionCardsGroupOption), ref _selectedInspectionCardsGroupOption, value)
}
并在您的视图中
<ComboBox ItemsSource="{Binding AllInspectionCardsGroupOptions}"
DisplayMemberPath="Display"
SelectedValuePath="Value"
SelectedValue="{Binding SelectedAllInspectionCardsGroupOptions, mode=TwoWay}"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.