एघ, मैंने बहुत जल्द बात की! वहाँ a perfectly good solution, कम से कम सिल्वरलाइट 3. में है (यह केवल 3 में हो सकता है, के बाद से this thread इंगित करता है कि इस सामग्री से संबंधित एक बग सिल्वरलाइट में तय किया गया था 3.)
मूल रूप से, आप ItemsSource
संपत्ति के लिए एक एकल कनवर्टर की जरूरत है , लेकिन यह किसी भी प्रतिबंधित विधियों का उपयोग किए बिना पूरी तरह से सामान्य हो सकता है, जब तक कि आप इसे उस संपत्ति का नाम पारित करें जिसका प्रकार MyEnum
है। और SelectedItem
पर डाटाबेसिंग पूरी तरह से दर्द रहित है; कोई कनवर्टर की जरूरत नहीं है! खैर, कम से कम यह तब तक है जब तक आप प्रत्येक enum मान के लिए कस्टम स्ट्रिंग नहीं चाहते हैं उदा। DescriptionAttribute
, हम्म ... शायद उस के लिए एक और कनवर्टर की आवश्यकता होगी; उम्मीद है कि मैं इसे सामान्य बना सकता हूं।
अद्यतन: मैंने कनवर्टर बनाया और यह काम करता है! मुझे अब SelectedIndex
से बांधना है, दुख की बात है, लेकिन यह ठीक है।इन लोगों का उपयोग करें:
<ComboBox x:Name="MonsterGroupRole"
ItemsSource="{Binding MonsterGroupRole,
Mode=OneTime,
Converter={StaticResource EnumToIEnumerableConverter}}"
SelectedIndex="{Binding MonsterGroupRole,
Mode=TwoWay,
Converter={StaticResource EnumToIntConverter}}" />
और संसाधन-घोषणा XAML इस तरह की:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
namespace DomenicDenicola.Wpf
{
public class EnumToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Note: as pointed out by Martin in the comments on this answer, this line
// depends on the enum values being sequentially ordered from 0 onward,
// since combobox indices are done that way. A more general solution would
// probably look up where in the GetValues array our value variable
// appears, then return that index.
return (int)value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Enum.Parse(targetType, value.ToString(), true);
}
}
public class EnumToIEnumerableConverter : IValueConverter
{
private Dictionary<Type, List<object>> cache = new Dictionary<Type, List<object>>();
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var type = value.GetType();
if (!this.cache.ContainsKey(type))
{
var fields = type.GetFields().Where(field => field.IsLiteral);
var values = new List<object>();
foreach (var field in fields)
{
DescriptionAttribute[] a = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (a != null && a.Length > 0)
{
values.Add(a[0].Description);
}
else
{
values.Add(field.GetValue(value));
}
}
this.cache[type] = values;
}
return this.cache[type];
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
बाध्यकारी XAML की इस तरह के साथ
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ddwpf="clr-namespace:DomenicDenicola.Wpf">
<Application.Resources>
<ddwpf:EnumToIEnumerableConverter x:Key="EnumToIEnumerableConverter" />
<ddwpf:EnumToIntConverter x:Key="EnumToIntConverter" />
</Application.Resources>
</Application>
किसी भी टिप्पणी की सराहना की जाएगी, के रूप में मैं कुछ हद तक एक्सएएमएल/सिल्वरलाइट/डब्ल्यूपीएफ/आदि। नौसिखिया। उदाहरण के लिए, EnumToIntConverter.ConvertBack
धीमा हो जाएगा, ताकि मुझे कैश का उपयोग करने पर विचार करना चाहिए?
निश्चित रूप से सभी सामग्री प्रकार वस्तु के साथ कर रहे हैं (यानी GetFields()) के रूप में यह प्रतिबिंब है और आम तौर पर धीमी गति से माना जाता (हालांकि निश्चित रूप उस पर निर्भर कैश आपके आवेदन का प्रतिबिंब का उपयोग)। उस अच्छे काम के अलावा! –
बहुत उपयोगी है। धन्यवाद। क्या आपने कभी भी मूल्यों के आसान अनुवाद के लिए इसे विस्तारित करने के लिए गोल किया है - जैसे ऑर्डरस्टैटस.NewOrder "नया ऑर्डर"? –
दरअसल, उपर्युक्त कोड एनम फ़ील्ड्स में जोड़े गए किसी भी 'विवरण एट्रिब्यूट्स' को पार्स करेगा :)। – Domenic