2016-05-07 5 views
0

Я пытаюсь связать Enum с ComboBox. Я видел много людей, использующих ObjectDataProvider, но я не могу получить доступ к нему. Я также заметил, что некоторые люди используют его в пределах Window.Resources, а не Page.Resources, но я не могу найти, как он используется на Page.Resources. Я искал решение часами.Как использовать ObjectDataProvider для привязки перечисления к ComboBox в XAML

То, что я до сих пор:

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); 
    } 
} 
+0

Я немного не понимаю, как вы на самом деле вызываете конвертер. Просто, сколько кода вы оставили? –

+0

_ «Я не могу получить доступ к нему» _ - что это значит? Код, показанный выше, не может успешно использовать 'ObjectDataProvider', потому что вы объявили его с помощью пустого элемента. Он работает только при предоставлении необходимых значений. Сделано правильно, он будет работать нормально. Пожалуйста, предоставьте хороший [mcve], который четко показывает, что вы пробовали, а также описание _precise_ того, что пошло не так. –

ответ

0

Вот пример с объекта страницы (в соответствии с MSDN documentation есть никаких ограничений на использование ObjectDataProvider со страницей):

Update # 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 
} 

Как это выглядит: here.

P.S. Здесь вам не нужны конвертеры. С уважением.

+0

@ andas1951 см. Обновленную версию, здесь я использовал атрибут Display, как вы пробовали. – Ilan

+0

Большое спасибо за объяснение :)! – andas1951

+0

не стесняйтесь отмечать это как ответ, в случае, если это было полезно. – Ilan