[英]Data binding Int property to Enum in WPF
以下是我所擁有的課程的簡化示例:
public class ExampleClassDto
{
public int DriverTypeId
}
我還有一個Enum,它將DriverType的Ids映射到有意義的名稱:
public enum DriverType
{
None,
Driver1,
Driver2,
Driver3
}
但是我希望將它在XAML中綁定到一個組合框。 不幸的是,由於類型不匹配,它不喜歡這個。 所以在我的ViewModel中,我必須創建第二個屬性來映射這兩個
public class ExampleViewModel
{
private ExampleClassDto _selectedExampleClass;
public ExampleClassDto SelectedExampleClass
{
get { return _selectedExampleClass; }
set
{
_selectedExampleClass = value;
SelectedDriverType = (DriverType)_selectedExampleClass.DriverTypeId;
OnPropertyChanged("SelectedDeviceType");
}
}
public DriverType SelectedDriverType
{
get
{
if (_selectedDeviceType != null)
{
return (DriverType)_selectedDeviceType.DriverTypeId;
}
return DriverType.None;
}
set
{
_selectedDeviceType.DriverTypeId = (int) value;
OnPropertyChanged("SelectedDriverType");
}
}
}
然后我綁定到新屬性。
<ComboBox ItemsSource="{Binding Source={StaticResource DriverTypeEnum}}" SelectedValue="{Binding SelectedDriverType, Mode=TwoWay}"/>
現在,這個工作,但感覺非常嚴重。 它使用SelectedDriverType作為轉換器。 我想避免讓DTO的屬性變成另一種類型。 還有其他更優雅的解決方案嗎?
謝謝!
您可以使用一個通用的轉換器說EnumConverter
,它將convert int to Enum
以在XAML上顯示它,並convert back from Enum to int
以在ViewModel類中重新設置。
它適用於任何枚舉類型。 你只需要在轉換器參數中傳遞枚舉類型。
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
Enum enumValue = default(Enum);
if (parameter is Type)
{
enumValue = (Enum)Enum.Parse((Type)parameter, value.ToString());
}
return enumValue;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
int returnValue = 0;
if (parameter is Type)
{
returnValue = (int)Enum.Parse((Type)parameter, value.ToString());
}
return returnValue;
}
}
XAML用法:
<ComboBox ItemsSource="{Binding Source={StaticResource DriverTypeEnum}}"
SelectedValue="{Binding DriverTypeId,
Converter={StaticResource EnumConverter},
ConverterParameter={x:Type local:DriverType}}"/>
local
是聲明DriverType的名稱空間。
接受的答案要求您在每個綁定上將枚舉類型指定為轉換器參數。
如果綁定到枚舉屬性,則轉換器可以從targetType
屬性確定枚舉類型,這可能更符合人體工程學且不易出錯。
public sealed class BidirectionalEnumAndNumberConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
if (targetType.IsEnum)
{
// convert int to enum
return Enum.ToObject(targetType, value);
}
if (value.GetType().IsEnum)
{
// convert enum to int
return System.Convert.ChangeType(
value,
Enum.GetUnderlyingType(value.GetType()));
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// perform the same conversion in both directions
return Convert(value, targetType, parameter, culture);
}
}
無論基礎枚舉類型( int
, short
, byte
...)如何,這也都有效。
調用時,此轉換器僅基於value
和targetType
值在int / enum值之間翻轉值的類型。 源代碼中沒有硬編碼的枚舉類型,因此它非常可重用。
首先將枚舉存儲為int是一個壞主意。 無論如何,我會使用雙向代理屬性而不是單獨的類:
public int DriverTypeId { get; set; }
public DriverType IntAsEnum // proxy property, doesn't store any value, only does the conversion
{
get { return (DriverType)DriverTypeId; }
set { DriverTypeId = (int)value; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.