实际上,我可以使用Combobox
将Enum
绑定到DescriptionAttribute
:
<ComboBox ItemsSource="{Binding Source={extension:Enumeration {x:Type model:MyEnum}}}"
DisplayMemberPath="Description"
SelectedValue="{Binding Path=DataContextEnumProp}"
SelectedValuePath="Value"/>
我使用了this SO answer
我的枚举是:
public enum MyEnum
{
[XmlEnum("first")]
[Description("first")]
FirstEnumMember,
[XmlEnum("second")]
[Description("second")]
SecondEnumMember,
//[XmlIgnore]
[Description("second")]
AlternativeToSecondEnumMember //I don't want this one to be in the combobox
}
我需要隐藏AlternativeToSecondEnumMember
,因为在ComboBox
中看到它是无关紧要的。
要做到这一点,最好的解决方案是什么?可能是Converter
或在代码中设置ItemsSource
吗?
答案 0 :(得分:3)
这是一些使用ObjectDataProvider特殊实现的基于属性的解决方案。因此,如果Enum字段由ShouldBeHiddenAttribute修饰且其值为true,则枚举字段将隐藏在UI(ComboBox)中。
ShouldBeHiddenAttribute代码
/// <summary>
/// helps to hide the enum value
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class ShouldBeHiddenAttribute : Attribute
{
public ShouldBeHiddenAttribute(bool isHiddenInUi)
{
HiddenInUi = isHiddenInUi;
}
public bool HiddenInUi { get; set; }
}
您的枚举装饰了我的属性
public enum MyEnum
{
[XmlEnum("first")]
[Description("first")]
FirstEnumMember,
[XmlEnum("second")]
[Description("second")]
SecondEnumMember,
//[XmlIgnore]
[Description("second")]
[ShouldBeHiddenAttribute(true)]
AlternativeToSecondEnumMember
//I don't want this one to be in the combobox
}
特殊ObjectDataProvider实施
/// <summary>
/// helps to display value according to decorating attributes
/// </summary>
public class AttributeBasedObjectDataProvider : ObjectDataProvider
{
/// <summary>
/// returns value of enum according its two attributes
/// 1. DescriptionAttribute - provide a dispaly name of the enum value
/// 2. ShouldBeHiddenAttribute - provide a dispaly state of the enum
/// </summary>
/// <param name="enumObj">enum field value</param>
/// <returns>if ShouldBeHiddenAttribute.HiddenInUi value is true return null else enum Description if defined(or enum actual value id Description is not defined)</returns>
public object GetEnumValues(Enum enumObj)
{
//get the ShouldBeHiddenAttribute value
var isHidden = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (ShouldBeHiddenAttribute), false).
SingleOrDefault() as ShouldBeHiddenAttribute;
if (isHidden != null && isHidden.HiddenInUi) return null;
//get the DescriptionAttribute value
var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (DescriptionAttribute), false).
SingleOrDefault() as DescriptionAttribute;
return attribute == null ? enumObj.ToString() : attribute.Description;
}
/// <summary>
/// returns collection of enum values
/// </summary>
/// <param name="type">enum type</param>
/// <returns>collection of enum values</returns>
public List<object> GetShortListOfApplicationGestures(Type type)
{
var shortListOfApplicationGestures =
Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).Where(o => o != null).ToList();
return
shortListOfApplicationGestures;
}
}
Xaml ObjectDataProvider定义
<ObjectDataProvider x:Key="MyEnumMembers" MethodName="GetShortListOfApplicationGestures" ObjectType="{x:Type pageBasedApp:AttributeBasedObjectDataProvider}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="pageBasedApp:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
组合绑定
<ComboBox ItemsSource="{Binding Source={StaticResource MyEnumMembers}}" Width="150"/>
问候。
答案 1 :(得分:2)
我建议使用简单的解决方案让您的生活更轻松。假设您正在使用MVVM,您只需创建一个新属性来保存合适值的列表。
private ObservableCollection<string> _myEnumList;
public ObservableCollection<string> MyEnumList
{
get
{
if (this._myEnumList == null)
{
string[] myList = Enum.GetNames(typeof(MyEnum));
// You can also use your own logic to generate your list
this._myEnumList = new ObservableCollection<string>(myList);
}
return this._myEnumList;
}
}
我个人认为,当Enum
中的所有值都无效时,尝试找到将Enum
类型自动转换为字符串值列表的方法毫无意义。< / p>
答案 2 :(得分:0)
我能够使用this solution中的"(A,B,C)"
和key = db.Key.from_path('Model', int(id))
找到一种方法来做我想做的事情。由于链接大约是obj = db.get(key)
而不是<div class="input-field col s12 m12 l12">
<input id="birthdate" type="date" class="datepicker" name="birthdate">
<label for="birthdate">Birthdate</label>
</div>
<div id="birthdate-icon" class="cursor-pointer">
<i class="material-icons">today</i>
</div>
,为了便于阅读,我在这里提出了对我有用的内容。
首先,我必须在$(document).ready(function(){
$('.datepicker').pickadate({
selectMonths: true,
selectYears: 150,
format: 'yyyy-mm-dd',
min: new Date(1900,1,1),
max: true
});
initBindings();
});
function initBindings(){
$('#birthdate-icon').click(function(){
$('#birthdate').click();
});
}
中添加Converter
:
DataTrigger
然后创建IsEnabled
:
IsVisible
DataTrigger
为here
答案 3 :(得分:0)
由于您曾经写过要避免在VM中将string
转换为MyEnum
的情况,因此这里是一种没有string
的解决方案:
public ObservableCollection<MyEnum> MyEnumList { get; } = new ObservableCollection<MyEnum>(
Enum.GetValues(typeof(MyEnum)).
Cast<MyEnum>().
Where(myEnum => myEnum != MyEnum.AlternativeToSecondEnumMember));
通过这种方式,您可以继续使用MyEnum
,而无需进行string
的转换。
答案 4 :(得分:0)
这就是我找到的解决方案:
public static IList ToList(this Type type, Enum[] valuesToSkip)
{
ArrayList enumList = new ArrayList();
Array enumValues = Enum.GetValues(type);
foreach (Enum value in enumValues)
{
if (valuesToSkip.Contains(value))
continue;
// in this solution I had a method to get the description from the Enum
// but you can avoid this part and populate your list with the enum values
//enumList.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value)));
enumList.Add(value);
}
return list;
}
我已经编写了自己的ToList方法,该方法可以返回枚举,但不包括我通过valuesToSkip传递的枚举。 我以这种方式填充组合框:
comboBox.DataSource = EnumExtension.ToList(typeof(yourEnum),新的Enum [] {yourEnum.ValueToSkip});