আমি আমার কাছে সংজ্ঞায়িত করা বাধ্যতামূলক সমস্ত বস্তুর জন্য পছন্দ করি ViewModel
তাই আমি <ObjectDataProvider>
যখন সম্ভব হয় তখন xaml এ ব্যবহার এড়াতে চেষ্টা করি ।
আমার সমাধানটি ভিউতে সংজ্ঞায়িত কোনও ডেটা এবং কোনও কোড-পিছনে ব্যবহার করে না। কেবলমাত্র একটি ডাটাবাইন্ডিং, একটি পুনরায় ব্যবহারযোগ্য ভ্যালু কনভার্টার, কোনও এনুম প্রকারের জন্য বিবরণ সংগ্রহের একটি পদ্ধতি এবং এর সাথে বাঁধতে ভিউমোডেলে একক সম্পত্তি।
যখন আমি একটি বাঁধাই করার চান Enum
একটি থেকে ComboBox
টেক্সট আমি প্রদর্শন করতে চাই না মান সাথে মেলে Enum
, তাই আমি ব্যবহার [Description()]
অ্যাট্রিবিউট এটা যে টেক্সট আমি আসলে দেখতে চান দিতে ComboBox
। আমার যদি সপ্তাহের বেশ কয়েকটি দিন থাকে তবে এটি দেখতে কিছুটা এমন দেখাবে:
public enum DayOfWeek
{
// add an optional blank value for default/no selection
[Description("")]
NOT_SET = 0,
[Description("Sunday")]
SUNDAY,
[Description("Monday")]
MONDAY,
...
}
প্রথম আমি এনামগুলিকে মোকাবেলার জন্য কয়েকটি পদ্ধতি সহ সহায়ক শ্রেণি তৈরি করেছি। একটি পদ্ধতি একটি নির্দিষ্ট মানের জন্য একটি বিবরণ পায়, অন্য পদ্ধতিটি একটি মানের জন্য সমস্ত মান এবং তাদের বিবরণ পায়।
public static class EnumHelper
{
public static string Description(this Enum value)
{
var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Any())
return (attributes.First() as DescriptionAttribute).Description;
// If no description is found, the least we can do is replace underscores with spaces
// You can add your own custom default formatting logic here
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
return ti.ToTitleCase(ti.ToLower(value.ToString().Replace("_", " ")));
}
public static IEnumerable<ValueDescription> GetAllValuesAndDescriptions(Type t)
{
if (!t.IsEnum)
throw new ArgumentException($"{nameof(t)} must be an enum type");
return Enum.GetValues(t).Cast<Enum>().Select((e) => new ValueDescription() { Value = e, Description = e.Description() }).ToList();
}
}
এর পরে, আমরা একটি তৈরি করি ValueConverter
। উত্তরাধিকার সূচনাটি MarkupExtension
এক্সএএমএল-তে ব্যবহার করা সহজ করে তোলে যাতে এটি এটিকে একটি উত্স হিসাবে ঘোষণা করতে হবে না।
[ValueConversion(typeof(Enum), typeof(IEnumerable<ValueDescription>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return EnumHelper.GetAllValuesAndDescriptions(value.GetType());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
আমার ViewModel
কেবলমাত্র 1 টি সম্পত্তি দরকার যা আমার এবং কম্বোবক্স View
উভয়ের জন্য আবদ্ধ করতে পারে :SelectedValue
ItemsSource
private DayOfWeek dayOfWeek;
public DayOfWeek SelectedDay
{
get { return dayOfWeek; }
set
{
if (dayOfWeek != value)
{
dayOfWeek = value;
OnPropertyChanged(nameof(SelectedDay));
}
}
}
এবং অবশেষে ComboBox
দর্শনটি বাঁধতে ( বাঁধাইয়ের ValueConverter
মধ্যে ব্যবহার করে ItemsSource
) ...
<ComboBox ItemsSource="{Binding Path=SelectedDay, Converter={x:EnumToCollectionConverter}, Mode=OneTime}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
SelectedValue="{Binding Path=SelectedDay}" />
এই সমাধানটি বাস্তবায়নের জন্য আপনাকে কেবল আমার EnumHelper
ক্লাস এবং EnumToCollectionConverter
ক্লাসের অনুলিপি করতে হবে । তারা যে কোনও এনামের সাথে কাজ করবে । এছাড়াও, আমি এটি এখানে অন্তর্ভুক্ত করিনি, তবে ValueDescription
ক্লাসটি কেবল একটি সরল শ্রেণি যেখানে 2 টি পাবলিক অবজেক্ট বৈশিষ্ট্য রয়েছে, যাকে বলা হয় Value
, বলা হয় Description
। আপনি নিজে তৈরি করতে পারেন বা আপনি কোড ব্যবহার করতে একটি Tuple<object, object>
বা ব্যবহার করতে পারেনKeyValuePair<object, object>