是否有更好的方法在控件中显示枚举,例如组合框

时间:2015-05-21 06:00:00

标签: c# enums winrt-xaml win-universal-app

我的目标是以用户友好的字符串格式而不是代码值向用户呈现可用枚举列表,并在需要时显示所述属性。 鉴于DataAnnotations名称空间在8.1通用应用程序中不存在,我不能简单地应用[Display(Name="Nice display string")]

相反,我使用IValueConverter在传入的枚举上运行switch语句并返回我想要的字符串,反之亦然,如果无法转换将抛出异常。 在viewmodel中,我返回一个List<Enum>作为可绑定数据源(对于组合框),所选项目绑定到viewmodel中的相对属性。

测试时,这是有效的 - 字符串以用户友好的格式显示,属性正在改变并正确设置枚举值。但是,Visual Studio设计器(随机)会抛出一个xaml解析异常(由于combobox.itemtemplate上的绑定标记,我很可能会抛出它),这绝不是理想的。

所以,我的问题 - 有没有更好的方法来实现我的目标而不抛出异常?即使应用程序编译并运行,xaml错误仍然需要关注吗?

我的转换器

public class FactToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        Fact input = (Fact)value;
        switch (input)
        {
            case Fact.Wrong:
                return "Your Fact is Incorect";
            case Fact.Right:
                return "Your Fact is Correct";
            default:
                throw new ArgumentOutOfRangeException("value", "Fact to string conversion failed as selected enum value has no corresponding string output set up.");
        }
    }
}

My Bindable Itemssource

public List<Fact> FactList
{
    get
    {
        return new List<Fact>
        {
            Fact.Wrong,
            Fact.Right,
        };
    }
}

和我的xaml

<ComboBox Header="Sample Fact:" Margin="0,10" ItemsSource="{Binding FactList}"
          SelectedItem="{Binding CurrentFact, Mode=TwoWay}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <Grid DataContext="{Binding}">
                <TextBlock Text="{Binding Converter={StaticResource FactConv}}"/>
            </Grid>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

3 个答案:

答案 0 :(得分:1)

仅仅因为缺少DisplayAnnotations命名空间,并不意味着您无法使用Display。只需创建自己的属性类。 Please see this answer to another question for how to do that

答案 1 :(得分:1)

显示属性实现

[System.AttributeUsage(System.AttributeTargets.All)]
public class Display : System.Attribute
{
    private string _name;
    public Display(string name)
    { _name = name; }
    public string GetName()
    { return _name; }
}

转换器

public class EnumWithDisplayConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        try
        {
            string output = value.GetType()
                .GetTypeInfo()
                .GetDeclaredField(((Enum)value).ToString())
                .GetCustomAttribute<Display>()
                .GetName();
            return output;
        }
        catch (NullReferenceException)
        {
            return ((Enum)value).ToString();
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

答案 2 :(得分:0)

VS设计师无缘无故地随机抛出一些例外,所以它并不是那么重要。现在,如果在运行时抛出异常 - 这是一个严重的问题,你需要解决它!

旁注:您DataContext={Binding}中的Grid上不需要DataTemplate