如何使用ObjectDataProvider在XAML中将枚举绑定到ComboBox

3
我正在尝试将一个枚举类型绑定到ComboBox上。我看到很多人使用ObjectDataProvider,但我似乎无法访问它。我也注意到有些人将其放在Window.Resources中而不是Page.Resources中,但我找不到如何在Page.Resources中使用它。我已经寻找解决方案几个小时了。
我目前所拥有的:
XAML
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Sports;assembly=Sports"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ViewModel="using:Sports.ViewModel"
xmlns:model="using:Sports.Model"
xmlns:system="using:System"


x:Class="Sports.MainPage"
mc:Ignorable="d">

<Page.DataContext>
    <ViewModel:CreateSubsVM/>
</Page.DataContext>
    <Page.Resources>

    <ObjectDataProvider></ObjectDataProvider>
    </Page.Resources>
  </Grid>
</Page>

C#

public enum SubsAmount
{
    [Display(Description = "One Year")]
    Oneyear = 0,
    [Display(Description = "Two Years")]
    TwoYears = 1,
    [Display(Description = "Three Years")]
    ThreeYears = 2
}


public class ComboboxConverter: IValueConverter
{

    public string GetEnumValues(Enum enumObj)
    {
        DisplayAttribute attribute = enumObj.GetType().
        GetRuntimeField(enumObj.ToString()).
        GetCustomAttributes(typeof(SubsAmount), false).
        SingleOrDefault() as DisplayAttribute;
        return attribute == null ? enumObj.ToString() : attribute.Description;
    }


    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return GetEnumValues((Enum) value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return Enum.ToObject(targetType, value);
    }
}

我有点不清楚你实际上是如何调用转换器的。你省略了多少代码? - 15ee8f99-57ff-4f92-890c-b56153
“我似乎无法访问它”——这是什么意思?你上面展示的代码不能成功使用ObjectDataProvider,因为你使用一个空元素进行了声明。只有提供必要的值才能使其正常工作。如果正确操作,它将会正常运作。请提供一个良好的[mcve],清楚地展示你尝试过的所有内容,并提供一个精确的描述出现了什么问题。 - Peter Duniho
1个回答

5

这里有一个与页面对象相关的示例(根据MSDN 文档,没有任何限制与页面一起使用ObjectDataProvider):

更新 #1

Xaml

<Page x:Class="PageBasedApp.MyPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:pageBasedApp="clr-namespace:PageBasedApp"
  mc:Ignorable="d" 
  d:DesignHeight="300" d:DesignWidth="300"
Title="MyPage">
<Page.Resources>
    <ObjectDataProvider x:Key="Gestures" MethodName="GetValues" ObjectType="{x:Type ApplicationGesture}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="ApplicationGesture" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    <ObjectDataProvider x:Key="SubAmounts" MethodName="GetShortListOfApplicationGestures" ObjectType="{x:Type pageBasedApp:DisplayAttributeBasedObjectDataProvider}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="pageBasedApp:SubsAmount" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Page.Resources>

<Grid>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
        <Label Content="All Gestures:"/>
        <ComboBox ItemsSource="{Binding Source={StaticResource Gestures}}" Width="150"/>
        <Label Content="Sub Amounts:"/>
        <ComboBox ItemsSource="{Binding Source={StaticResource SubAmounts}}" Width="150"/>
    </StackPanel>
</Grid>

这里是自定义数据提供程序代码

public class DisplayAttributeBasedObjectDataProvider : ObjectDataProvider
{
    public object GetEnumValues(Enum enumObj)
    {
        var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
            GetCustomAttributes(typeof(DisplayAttribute), false).
            SingleOrDefault() as DisplayAttribute;
        return attribute == null ? enumObj.ToString() : attribute.Description;
    }

    public List<object> GetShortListOfApplicationGestures(Type type)
    {
        var shortListOfApplicationGestures = Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).ToList();
        return
            shortListOfApplicationGestures;
    }
}

属性代码和枚举:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class DisplayAttribute : Attribute
{
    public DisplayAttribute(string displayName)
    {
        Description = displayName;
    }

    public string Description { get; set; }
}

public enum SubsAmount
{
    [Display("One Year")]
    Oneyear = 0,
    [Display("Two Years")]
    TwoYears = 1,
    [Display("Three Years")]
    ThreeYears = 2
}

我来翻译一下,内容涉及编程。请注意保留HTML标签和格式。

How it looks like: here.

P.S. 这里不需要使用任何转换器。 谢谢。


@andas1951,请查看更新版本,我已经像你尝试的那样使用了Display属性。 - Ilan
非常感谢您的解释 :)! - andas1951
请将以下与编程有关的内容从英语翻译成中文。返回仅翻译后的文本:如果有帮助,请随意将其标记为已回答。 - Ilan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接