কীভাবে রেডিওবাটনগুলিকে একটি এনামের সাথে বাঁধবেন?


406

আমি এই জাতীয় একটি এনাম পেয়েছি:

public enum MyLovelyEnum
{
    FirstSelection,
    TheOtherSelection,
    YetAnotherOne
};

আমি আমার ডেটা কনটেক্সটে একটি সম্পত্তি পেয়েছি:

public MyLovelyEnum VeryLovelyEnum { get; set; }

এবং আমি আমার ডাব্লুপিএফ ক্লায়েন্টে তিনটি রেডিওবটন পেয়েছি।

<RadioButton Margin="3">First Selection</RadioButton>
<RadioButton Margin="3">The Other Selection</RadioButton>
<RadioButton Margin="3">Yet Another one</RadioButton>

এখন আমি কীভাবে যথাযথ দ্বিমুখী বাইন্ডিংয়ের জন্য রেডিওবটনগুলিকে সম্পত্তিতে বেঁধে দেব?


3
আপনি আপনার XAML মধ্যে পৃথক RadioButtons উল্লেখ না করে এই কাজ করতে, তাহলে হয়তো আমি একটা তালিকা বাক্সে মত enum মান আবদ্ধ সুপারিশ করবে এই বা এই , এবং যে মত ব্যবহার RadioButtons করার ওভাররাইট আইটেমটি টেমপ্লেট হয়েছে এই
রাচেল

উত্তর:


389

আপনি আরও জেনেরিক রূপান্তরকারী ব্যবহার করতে পারেন

public class EnumBooleanConverter : IValueConverter
{
  #region IValueConverter Members
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
      return DependencyProperty.UnsetValue;

    if (Enum.IsDefined(value.GetType(), value) == false)
      return DependencyProperty.UnsetValue;

    object parameterValue = Enum.Parse(value.GetType(), parameterString);

    return parameterValue.Equals(value);
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
        return DependencyProperty.UnsetValue;

    return Enum.Parse(targetType, parameterString);
  }
  #endregion
}

এবং এক্সএএমএল-অংশে আপনি ব্যবহার:

<Grid>
    <Grid.Resources>
      <l:EnumBooleanConverter x:Key="enumBooleanConverter" />
    </Grid.Resources>
    <StackPanel >
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=FirstSelection}">first selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=TheOtherSelection}">the other selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=YetAnotherOne}">yet another one</RadioButton>
    </StackPanel>
</Grid>

51
আমার জন্য একটি কবজ মত কাজ। সংযোজন হিসাবে আমি কনভার্টব্যাককে "মিথ্যা" -র উপর আনসেটওয়ালু ফিরিয়ে আনার জন্যও পরিবর্তন করেছি, কারণ রূপালী আলো (এবং সম্ভবত ডাব্লুপিএফ যথাযথ) দুবার রূপান্তরকারীকে কল করে - একবার পুরাতন রেডিও বোতামের মানটি সেট না করে আবার নতুন সেট করার জন্য set আমি সম্পত্তি সেটারের বাইরে অন্য জিনিসগুলি ঝুলিয়ে রেখেছিলাম তাই আমি কেবল এটি একবার ডাকতে চেয়েছিলাম। - যদি (প্যারামিটারস্ট্রিং == নাল || মান। সমান (মিথ্যা)) ডিপেন্ডেন্সিপোপার্টি.উনসেটভ্যালু;
মার্কস করুন

8
থেকে আমি কি বলতে পারেন, এই আবশ্যক সম্পন্ন করা যদি না রেডিও বোতাম বিভিন্ন দলে দলে (এবং আমি যতদূর জানি বোতাম GROUPNAME সেট একই পিতা বা মাতা আছে ছাড়া একই দলের ডিফল্টভাবে এমন)। অন্যথায়, সম্পত্তিটি "বাউন্স" সেট করার জন্য কলগুলি এবং বিজোড় আচরণের ফলস্বরূপ।
nlawalker

2
হ্যাঁ তবে যদি আপনি মিথ্যাতে সেট করার সময় কনভার্টারে আনসেটকে কল করেন তবে এটি সত্যিকারের এনামমোটোবুলিয়ান কনভার্টার নয় বরং আরও একটি এনামমোটোর্যাডিয়ো বাটনকনভার্টার। সুতরাং পরিবর্তে আমি আমার সম্পত্তি সেটারে মানটি পৃথক কিনা তা পরীক্ষা করে দেখছি: যদি (_myEnumBackingField == মান) ফিরে আসে;
স্টাফেন

8
এই সমাধানের বাঁধাই কেবল একপথে সঠিকভাবে কাজ করে। বাঁধাই করা সম্পত্তি অন্য একটি মানকে নির্ধারিত করে আমি প্রোগ্রামিয়ালি রেডিয়াবাটন টগল করতে পারিনি। আপনি যদি সঠিক কাজের এবং আরও ভাল সমাধান চান তবে স্কট এর পদ্ধতির ব্যবহার করুন।
l46kok

2
@ মার্ক, সেই ক্ষেত্রে 'বাইন্ডিং.ডোনিথিং' না এবং 'ডিপেন্ডেন্সিপ্রোপার্টি.উনসেটভ্যালু' না ফেরার উপযুক্ত জিনিস নয় কি?
মার্ক এ। ডোনোহো

559

আপনি গ্রহণযোগ্য উত্তর আরও সরল করতে পারেন। Xaml এ স্ট্রিং হিসাবে এনামগুলি টাইপ করার পরিবর্তে এবং আপনার কনভার্টারে প্রয়োজনের চেয়ে আরও বেশি কাজ করার পরিবর্তে আপনি স্ট্রিং উপস্থাপনের পরিবর্তে এনামের মানগুলিতে স্পষ্টভাবে পাস করতে পারেন এবং ক্রিমসনএক্স মন্তব্য করেছেন, রানটাইমের পরিবর্তে সংকলনের সময় ত্রুটিগুলি ছুঁড়ে ফেলা হয়:

রূপান্তরকারীপ্যারামিটার = {x: স্থিতিশীল স্থানীয়: আপনারইউনটাইম.ইমনাম 1

<StackPanel>
    <StackPanel.Resources>          
        <local:ComparisonConverter x:Key="ComparisonConverter" />          
    </StackPanel.Resources>
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum1}}" />
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum2}}" />
</StackPanel>

তারপরে রূপান্তরকারীটিকে সহজ করুন:

public class ComparisonConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value?.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value?.Equals(true) == true ? parameter : Binding.DoNothing;
    }
}

সম্পাদনা (16 ডিসেম্বর '10):

বাঁধন ফিরিয়ে দেওয়ার পরামর্শ দেওয়ার জন্য আননকে ধন্যবাদ। নির্ভরতাপ্রোপার্টি.অনসেটভ্যালু ছাড়া কিছু না।


দ্রষ্টব্য - একই পাত্রে রেডিওব্যাটনের একাধিক গোষ্ঠী (ফেব্রুয়ারী 17 '11):

এক্সএএমএল-তে, যদি রেডিও বোতামগুলি একই প্যারেন্ট পাত্রে ভাগ করে, তবে একটি নির্বাচন করলে সেই ধারকটির মধ্যে থাকা সমস্ত অন্যান্য ডি-সিলেক্ট হবে (এমনকি তারা অন্য কোনও সম্পত্তিতে আবদ্ধ থাকলেও)। সুতরাং আপনার রেডিওবটনগুলি স্ট্যাক প্যানেলের মতো তাদের নিজস্ব পাত্রে একসাথে গোষ্ঠীযুক্ত একটি সাধারণ সম্পত্তিকে আবদ্ধ করার চেষ্টা করুন। আপনার সম্পর্কিত রেডিওব্যাটনগুলি একটি একক পিতামাতার ধারক ভাগ করে নিতে পারে না, তারপরে প্রতিটি রেডিওবাটনের গ্রুপনেম সম্পত্তিটিকে যৌক্তিকভাবে গ্রুপ করার জন্য একটি সাধারণ মান হিসাবে সেট করুন to


সম্পাদনা (এপ্রিল 5 '11):

সরলিকৃত কনভার্টব্যাকের যদি-অন্যথায় কোনও টার্নারি অপারেটর ব্যবহার করতে হয়।


দ্রষ্টব্য - এনুম টাইপ একটি ক্লাসে নেস্টেড (এপ্রিল 28 '11):

আপনার enum প্রকার (বরং নামস্থান সরাসরি বেশি) কোন ক্লাসে নেস্টেড হলে, আপনি XAML মধ্যে enum অ্যাক্সেস করতে + সিনট্যাক্স ব্যবহার করতে পারবেন যেমন প্রশ্নের একটি (হিসাবে চিহ্নিত নয়) উত্তর বিবৃত হতে পারে খুঁজে পাওয়া যায়নি ডাব্লুপিএফ-তে স্থির রেফারেন্সের জন্য এনাম টাইপ করুন :

রূপান্তরকারীপ্যারামিটার = {x: স্থিতিশীল স্থানীয়: আপনারক্লাস + আপনার নেস্টেডনাম টাইপ.ইনুম 1

এই মাইক্রোসফ্ট কানেক্ট ইস্যুর কারণে , তবে, ভিএস 2010-এর ডিজাইনার আর স্টেটিং লোড করবে না "Type 'local:YourClass+YourNestedEnumType' was not found.", তবে প্রকল্পটি সংকলন করে এবং সফলভাবে চলবে। অবশ্যই, আপনি যদি নিজের এনাম টাইপটি সরাসরি নেমস্পেসে স্থানান্তর করতে সক্ষম হন তবে আপনি এই সমস্যাটি এড়াতে পারেন।


সম্পাদনা করুন (জানুয়ারী 27 '12):

যদি এনাম পতাকা ব্যবহার করে তবে রূপান্তরটি নিম্নরূপ হবে:

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((Enum)value).HasFlag((Enum)parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

সম্পাদনা করুন (মে 715 '):

নালাম এনামের ক্ষেত্রে ( এটি প্রশ্নে জিজ্ঞাসা করা হয় না , তবে কিছু ক্ষেত্রে এটি প্রয়োজন হতে পারে, যেমন: ডিআর থেকে ওআরএম নাল ফিরে আসে বা যখনই এটি বুঝতে পারে যে প্রোগ্রামটির যুক্তিতে মানটি সরবরাহ করা হয়নি), যোগ করতে ভুলবেন না রূপান্তর পদ্ধতিতে প্রাথমিক নাল চেক করুন এবং উপযুক্ত বুল মানটি ফিরিয়ে দিন, এটি সাধারণত মিথ্যা (যদি আপনি কোনও রেডিও বোতাম নির্বাচিত না চান), নীচের মত:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) {
            return false; // or return parameter.Equals(YourEnumType.SomeDefaultValue);
        }
        return value.Equals(parameter);
    }

দ্রষ্টব্য - নাল রেফারেন্সএক্সেপশন (10 অক্টোবর '18):

একটি নালারফেরান এক্সেপশন নিক্ষেপ করার সম্ভাবনাটি সরাতে উদাহরণ আপডেট করে। IsCheckedপ্রত্যাবর্তন Nullable<Boolean>একটি যুক্তিসঙ্গত সমাধান বলে মনে হচ্ছে returning


26
আমি সম্মত, আমি বিশ্বাস করি এটি একটি আরও ভাল সমাধান। এছাড়াও, এই রূপান্তরটি ব্যবহারের ফলে সংকলনের সময় প্রকল্পটি বিরতি ঘটবে, রান সময় নয়, যদি গণনার মানগুলি পরিবর্তন করা হয়, তবে এটি একটি বড় সুবিধা।
ক্রিমসনএক্স

4
এটি অবশ্যই গ্রহণযোগ্যগুলির চেয়ে অনেক ভাল সমাধান। +1
অরপাজ

7
সুন্দর সমাধান। আমি যুক্ত করব যে এটি 2 মানের সাথে তুলনা করে কেবল একটি তুলনা রূপান্তরকারী। এটি তুলনামূলক
রূপান্তরকারী

5
@ স্কট, খুব সুন্দর এই রূপান্তরকারীটি ফ্ল্যাগের অ্যাট্রিবিউট সহ বা ছাড়াই যে কোনও ক্ষেত্রেই ভাল। তবে এই ফিল্টারটি পতাকা হিসাবে এনামের সাথে সরাসরি রূপান্তরকারী হিসাবে ব্যবহার করা বেশিরভাগ ক্ষেত্রে নির্বোধ হবে। কারণটি হ'ল সঠিক ফলাফল পেতে আপনার পূর্বের মান সহ বুলিয়ান ক্যালক (| = বা ^ =) অর্জন করা উচিত তবে কনভার্টারের আগের মানটিতে অ্যাক্সেস নেই। তারপরে আপনার প্রতিটি এনাম মানের জন্য একটি বুল যুক্ত করা উচিত এবং আপনার এমভিভিএম মডেলটিতে যথাযথ বুলিয়ান ক্যালক করা উচিত। কিন্তু প্রতিটি তথ্যের জন্য ধন্যবাদ, খুব দরকারী।
এরিক ওয়েললেট

2
উইন্ডোজ ফোন 8 এ (সম্ভবত উইন স্টোর অ্যাপ্লিকেশনগুলির ক্ষেত্রে) আমাদের এক্স: স্ট্যাটিক নেই, তাই আমরা সমাধানটি সরাসরি এখানে ব্যবহার করতে পারি না। তবে আইডিই / কমপ্লায়ার যথেষ্ট স্মার্ট, এবং সমস্ত স্ট্রিং লিটারেলের বিপরীতে স্ট্রিংটি দেখায় (যাইহোক আমার অনুমান)। উদাহরণস্বরূপ এই কাজগুলি <রেডিওবটন ইসচেকড = "inding বাইন্ডিং ট্র্যাকিংমোড, কনভার্টারপ্যারামিটার = ড্রাইভিং, কনভার্টার = {স্ট্যাটিক রিসোর্স এনামটিওবুলিয়ান কনভার্টর Mode, মোড = টু ওয়ে ay" /> ড্রাইভিংয়ের যে কোনও টাইপগুলি রান টাইমের পরিবর্তে ডিজাইনের / সংকলনের সময় ধরা পড়বে।
আদর্শ

26

EnumToBooleanConverter উত্তরের জন্য: DependencyProperty ফিরিয়ে দেওয়ার পরিবর্তে.উনসেটভ্যালু বাইন্ডিং ফিরে আসার বিষয়টি বিবেচনা করুন the যে ক্ষেত্রে রেডিও বোতামটি ইসচেকড মানটি মিথ্যা হয়ে যায় তার জন্য কিছুই নয়। পূর্ববর্তীটি একটি সমস্যা নির্দেশ করে (এবং ব্যবহারকারীকে একটি লাল আয়তক্ষেত্র বা অনুরূপ বৈধতা সূচকগুলি দেখাতে পারে) যখন পরবর্তীটি কেবল ইঙ্গিত করে যে কিছুই করা উচিত নয়, যা সে ক্ষেত্রে চেয়েছিল।

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback.aspx http: //msdn.mic Microsoft.com/en-us/library/system.windows.data.binding .donothing.aspx


সিলভারলাইটে কোনও বাঁধাই নেই N এটি কেবল ডাব্লুপিএফ। পরিবর্তে নাল ব্যবহার করুন।
আলেকজান্ডার ভ্যাসিলিভ

1
বাইন্ডিং.ও ইউডাব্লুপি থেকে কিছুই যায় নি।
ব্ল্যাকইস

5

আমি একটি তালিকাবক্সে রেডিওবটনগুলি ব্যবহার করব এবং তারপরে সিলেক্টভ্যালুতে আবদ্ধ হব।

এটি এই বিষয়টি সম্পর্কে একটি পুরানো থ্রেড, তবে বেস ধারণাটি একই হওয়া উচিত: http://social.msdn.microsoft.com/ Forums / en-US / wpf/ thread/ 323d067a-efef-4c9f-8d99-fecf45522395/


তালিকাক্স এবং ডেটা টেম্প্লেট ব্যবহার করে একই ধরণের পদ্ধতিতে দ্বি-দ্বার বাইন্ডিং পাই যাতে আপনার উচিত।
ব্রায়ান অ্যান্ডারসন

এই বাগ: geekswithblogs.net/claraoscura/archive/2008/10/17/125901.aspx আমার জন্য একটি দিন নষ্ট করে দিয়েছে।
স্ল্যাম্পেন

3
এটি এখন পর্যন্ত সর্বোত্তম সমাধান, অন্য সব কিছুর কারণে অনর্থক কোড হয়। ( একটি লিস্টবক্স ব্যবহারের আরেকটি উদাহরণ )
এইচবি

3

ইউডাব্লুপি-র জন্য, এটি এত সহজ নয়: প্যারামিটার হিসাবে ক্ষেত্রের মানটি পাস করতে আপনাকে অতিরিক্ত হুপ দিয়ে যেতে হবে।

উদাহরণ 1

ডাব্লুপিএফ এবং ইউডাব্লুপি উভয়ের জন্যই বৈধ।

<MyControl>
    <MyControl.MyProperty>
        <Binding Converter="{StaticResource EnumToBooleanConverter}" Path="AnotherProperty">
            <Binding.ConverterParameter>
                <MyLibrary:MyEnum>Field</MyLibrary:MyEnum>
            </Binding.ConverterParameter>
        </MyControl>
    </MyControl.MyProperty>
</MyControl>

উদাহরণ 2

ডাব্লুপিএফ এবং ইউডাব্লুপি উভয়ের জন্যই বৈধ।

...
<MyLibrary:MyEnum x:Key="MyEnumField">Field</MyLibrary:MyEnum>
...

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={StaticResource MyEnumField}}"/>

উদাহরণ 3

শুধুমাত্র ডাব্লুপিএফের জন্য বৈধ!

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static MyLibrary:MyEnum.Field}}"/>

ইউডাব্লুপি সমর্থন করে না x:Staticসুতরাং উদাহরণ 3 প্রশ্নের বাইরে রয়েছে; ধরুন আপনি উদাহরণ 1 দিয়ে যাচ্ছেন , ফলাফলটি আরও ভার্বোজ কোড code উদাহরণ 2 সামান্য ভাল, কিন্তু এখনও আদর্শ নয়।

সমাধান

public abstract class EnumToBooleanConverter<TEnum> : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;

        if (Parameter == null)
            return DependencyProperty.UnsetValue;

        if (Enum.IsDefined(typeof(TEnum), value) == false)
            return DependencyProperty.UnsetValue;

        return Enum.Parse(typeof(TEnum), Parameter).Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;
        return Parameter == null ? DependencyProperty.UnsetValue : Enum.Parse(typeof(TEnum), Parameter);
    }
}

তারপরে, প্রতিটি ধরণের জন্য আপনি সমর্থন করতে চান, একটি রূপান্তরকারী সংজ্ঞায়িত করুন যা এনাম টাইপের বাক্স করে।

public class MyEnumToBooleanConverter : EnumToBooleanConverter<MyEnum>
{
    //Nothing to do!
}

এটি বাক্সযুক্ত হওয়ার কারণ হ'ল কারণটিতে প্রকারটি উল্লেখ করার কোনও উপায় নেই ConvertBack পদ্ধতিতে ; বক্সিং যে যত্ন নেয়। আপনি যদি প্রথম দুটি উদাহরণের সাথে যান তবে আপনি বাক্সবিত্ত শ্রেণীর উত্তরাধিকারী হওয়ার প্রয়োজনীয়তা বাদ দিয়ে প্যারামিটারের প্রকারটি উল্লেখ করতে পারেন; যদি আপনি এটি সমস্ত এক লাইনে করতে চান এবং কমপক্ষে ভার্বোসিটি সম্ভব হয় তবে পরবর্তী সমাধানটি আদর্শ।

ব্যবহার উদাহরণ 2 এর সাথে সাদৃশ্যযুক্ত , তবে বাস্তবে এটি কম ভার্বোস।

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource MyEnumToBooleanConverter}, ConverterParameter=Field}"/>

নেতিবাচকতা হ'ল আপনি যে প্রতিটি ধরণের সমর্থন করতে চান তার জন্য আপনাকে অবশ্যই একটি কনভার্টারের সংজ্ঞা দিতে হবে।


1

আমি এনডুগুলিতে বাধ্যতামূলক রেডিওবটন এবং চেকবক্সগুলি পরিচালনা করতে একটি নতুন শ্রেণি তৈরি করেছি। এটি পতাকাযুক্ত এনামগুলির জন্য (একাধিক চেকবক্স নির্বাচন সহ) এবং একক-নির্বাচন চেকবক্স বা রেডিও বোতামগুলির জন্য অ-পতাকাযুক্ত এনামগুলির জন্য কাজ করে। এটির জন্য মোটেই কোনও ভ্যালু কনভার্টারের প্রয়োজন নেই।

এটি প্রথমে আরও জটিল দেখায়, তবে আপনি একবার এই প্রকল্পটি আপনার প্রকল্পে অনুলিপি করতে পারেন, এটি হয়ে গেছে। এটি জেনেরিক তাই এটি কোনও এনামের জন্য সহজেই পুনরায় ব্যবহার করা যায়।

public class EnumSelection<T> : INotifyPropertyChanged where T : struct, IComparable, IFormattable, IConvertible
{
  private T value; // stored value of the Enum
  private bool isFlagged; // Enum uses flags?
  private bool canDeselect; // Can be deselected? (Radio buttons cannot deselect, checkboxes can)
  private T blankValue; // what is considered the "blank" value if it can be deselected?

  public EnumSelection(T value) : this(value, false, default(T)) { }
  public EnumSelection(T value, bool canDeselect) : this(value, canDeselect, default(T)) { }
  public EnumSelection(T value, T blankValue) : this(value, true, blankValue) { }
  public EnumSelection(T value, bool canDeselect, T blankValue)
  {
    if (!typeof(T).IsEnum) throw new ArgumentException($"{nameof(T)} must be an enum type"); // I really wish there was a way to constrain generic types to enums...
    isFlagged = typeof(T).IsDefined(typeof(FlagsAttribute), false);

    this.value = value;
    this.canDeselect = canDeselect;
    this.blankValue = blankValue;
  }

  public T Value
  {
    get { return value; }
    set 
    {
      if (this.value.Equals(value)) return;
      this.value = value;
      OnPropertyChanged();
      OnPropertyChanged("Item[]"); // Notify that the indexer property has changed
    }
  }

  [IndexerName("Item")]
  public bool this[T key]
  {
    get
    {
      int iKey = (int)(object)key;
      return isFlagged ? ((int)(object)value & iKey) == iKey : value.Equals(key);
    }
    set
    {
      if (isFlagged)
      {
        int iValue = (int)(object)this.value;
        int iKey = (int)(object)key;

        if (((iValue & iKey) == iKey) == value) return;

        if (value)
          Value = (T)(object)(iValue | iKey);
        else
          Value = (T)(object)(iValue & ~iKey);
      }
      else
      {
        if (this.value.Equals(key) == value) return;
        if (!value && !canDeselect) return;

        Value = value ? key : blankValue;
      }
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged([CallerMemberName] string propertyName = "")
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

এবং কীভাবে এটি ব্যবহার করবেন, এর জন্য বলি যে আপনি কোনও কাজ ম্যানুয়ালি বা স্বয়ংক্রিয়ভাবে চালনার জন্য একটি এনাম রেখেছেন এবং সপ্তাহের যে কোনও দিন নির্ধারিত হতে পারে এবং কিছু alচ্ছিক বিকল্প ...

public enum StartTask
{
  Manual,
  Automatic
}

[Flags()]
public enum DayOfWeek
{
  Sunday = 1 << 0,
  Monday = 1 << 1,
  Tuesday = 1 << 2,
  Wednesday = 1 << 3,
  Thursday = 1 << 4,
  Friday = 1 << 5,
  Saturday = 1 << 6
}

public enum AdditionalOptions
{
  None = 0,
  OptionA,
  OptionB
}

এই ক্লাসটি ব্যবহার করা এখন কত সহজ easy

public class MyViewModel : ViewModelBase
{
  public MyViewModel()
  {
    StartUp = new EnumSelection<StartTask>(StartTask.Manual);
    Days = new EnumSelection<DayOfWeek>(default(DayOfWeek));
    Options = new EnumSelection<AdditionalOptions>(AdditionalOptions.None, true, AdditionalOptions.None);
  }

  public EnumSelection<StartTask> StartUp { get; private set; }
  public EnumSelection<DayOfWeek> Days { get; private set; }
  public EnumSelection<AdditionalOptions> Options { get; private set; }
}

এবং এই শ্রেণীর সাথে চেকবক্স এবং রেডিও বোতামগুলি বাঁধাই করা কত সহজ easy

<StackPanel Orientation="Vertical">
  <StackPanel Orientation="Horizontal">
    <!-- Using RadioButtons for exactly 1 selection behavior -->
    <RadioButton IsChecked="{Binding StartUp[Manual]}">Manual</RadioButton>
    <RadioButton IsChecked="{Binding StartUp[Automatic]}">Automatic</RadioButton>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or Many selection behavior -->
    <CheckBox IsChecked="{Binding Days[Sunday]}">Sunday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Monday]}">Monday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Tuesday]}">Tuesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Wednesday]}">Wednesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Thursday]}">Thursday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Friday]}">Friday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Saturday]}">Saturday</CheckBox>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or 1 selection behavior -->
    <CheckBox IsChecked="{Binding Options[OptionA]}">Option A</CheckBox>
    <CheckBox IsChecked="{Binding Options[OptionB]}">Option B</CheckBox>
  </StackPanel>
</StackPanel>
  1. যখন ইউআই লোড হবে, "ম্যানুয়াল" রেডিও বোতামটি নির্বাচন করা হবে এবং আপনি "ম্যানুয়াল" বা "স্বয়ংক্রিয়" এর মধ্যে আপনার নির্বাচনকে পরিবর্তন করতে পারবেন তবে তাদের মধ্যে একটি অবশ্যই সর্বদা নির্বাচন করা উচিত।
  2. সপ্তাহের প্রতিটি দিন চেক করা হবে না, তবে তাদের যে কোনও সংখ্যক চেক বা চেক করা যাবে না।
  3. "বিকল্প এ" এবং "বিকল্প বি" উভয়ই প্রাথমিকভাবে চেক করা হবে। আপনি একটি বা অন্যটিকে চেক করতে পারেন, একটিতে চেক করা অন্যটিকে অনিচ্ছুক করে তুলবে (রেডিওবটনগুলির অনুরূপ), তবে এখন আপনি উভয়কেই চেক করতে পারবেন না (যা আপনি ডাব্লুপিএফের রেডিওবটন দিয়ে করতে পারবেন না, এ কারণেই এখানে চেকবক্স ব্যবহৃত হচ্ছে)

মনে করুন স্টার্টটাস এনামে আপনার যেমন 3 টি আইটেম রয়েছে যেমন {অপরিজ্ঞাত, ম্যানুয়াল, স্বয়ংক্রিয়} আপনি ডিফল্ট করতে চান অপরিজ্ঞায়িত কারণ কোনও ব্যবহারকারী যতক্ষণ না কোনও মান নির্ধারণ না করে অবধি সংজ্ঞায়িত হয়। এছাড়াও: বাছাইকৃত আইটেমকে কীভাবে মোকাবেলা করা হয়? আপনার ভিউমোডেলের কোনও সিলেক্ট স্টার্টটাস্ক নেই।
ব্যবহারকারী 1040323

আমার ভিউমোডেলে স্টার্টআপ সম্পত্তিটি একটি EnumSelection<StartTask>বস্তু। আপনি যদি সংজ্ঞাটি EnumSelection<T>দেখে থাকেন তবে দেখতে পাবেন এটির একটি মূল্য সম্পত্তি রয়েছে। সুতরাং ভিউ মডেলটিতে একটি "সিলেক্ট স্টার্টটাস্ক" থাকা দরকার নেই। আপনি ব্যবহার করবেন StartUp.Value। এবং অপরিবর্তিতের একটি ডিফল্ট মান হিসাবে, তৃতীয় এনাম, অতিরিক্ত বিভাগ দেখুন, এটির একটি অপরিজ্ঞাত পরিবর্তে কোনও নেই, তবে আপনি যা চান তার নাম পরিবর্তন করতে পারেন।
নিক

1

এই কাজ চেকবক্স খুব।

public class EnumToBoolConverter:IValueConverter
{
    private int val;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int intParam = (int)parameter;
        val = (int)value;

        return ((intParam & val) != 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        val ^= (int)parameter;
        return Enum.Parse(targetType, val.ToString());
    }
}

একক এনামকে একাধিক চেকবক্সে বাঁধাই।


1
আপনি আমার পক্ষে যে অনুগ্রহ করেছেন তার জন্য আমি আপনাকে একটি বড় "ধন্যবাদ" বলি। এটি আমার জন্য কবজির মতো কাজ করেছে।
এলহাম আজাদফার

0

স্কট থেকে EnumToBooleanConverter এর উপর ভিত্তি করে। আমি লক্ষ্য করেছি যে কনভার্টব্যাক পদ্ধতি এনামে পতাকা কোড সহ কাজ করে না।

আমি নিম্নলিখিত কোড চেষ্টা করেছি:

public class EnumHasFlagToBooleanConverter : IValueConverter
    {
        private object _obj;
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            _obj = value;
            return ((Enum)value).HasFlag((Enum)parameter);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value.Equals(true))
            {
                if (((Enum)_obj).HasFlag((Enum)parameter))
                {
                    // Do nothing
                    return Binding.DoNothing;
                }
                else
                {
                    int i = (int)_obj;
                    int ii = (int)parameter;
                    int newInt = i+ii;
                    return (NavigationProjectDates)newInt;
                }
            }
            else
            {
                if (((Enum)_obj).HasFlag((Enum)parameter))
                {
                    int i = (int)_obj;
                    int ii = (int)parameter;
                    int newInt = i-ii;
                    return (NavigationProjectDates)newInt;

                }
                else
                {
                    // do nothing
                    return Binding.DoNothing;
                }
            }
        }
    }

আমি যে কাজ করতে পারছি না তা হ'ল একটি কাস্ট intকরা targetTypeতাই আমি এটিকে হার্ডকোড করেছিলাম NavigationProjectDates, যে এনামটি আমি ব্যবহার করি। এবং, targetType == NavigationProjectDates...


আরও জেনেরিক ফ্ল্যাগ এনাম কনভার্টারের জন্য সম্পাদনা করুন:

    পাবলিক ক্লাস ফ্ল্যাগসিনাম টো বুলিয়ান কনভার্টার: আইভ্যালু কনভার্টার {
        প্রাইভেট ইন্ট _ফ্লেগ = 0;
        পাবলিক অবজেক্ট কনভার্ট (বস্তুর মান, টাইপ টার্গেটটাইপ, অবজেক্ট প্যারামিটার, স্ট্রিং ল্যাঙ্গুয়েজ) {
            যদি (মান == নাল) মিথ্যা ফেরত দেয়;
            _ফ্লেগস = (অন্তর্নির্মিত) মান;
            টাইপ করুন = মান.গেটটাইপ ();
            অবজেক্ট o = Enum.ToObject (টি, প্যারামিটার);
            রিটার্ন ((এনাম) মান)। হাসফ্লেগ ((এনাম) ও);
        }

        পাবলিক অবজেক্ট কনভার্টব্যাক (অবজেক্টের মান, টাইপ টার্গেটটাইপ, অবজেক্ট প্যারামিটার, স্ট্রিং ল্যাঙ্গুয়েজ)
        {
            যদি (মান?। সমান (সত্য) ?? মিথ্যা) {
                _ফ্ল্যাগস = _ফ্ল্যাগস | (int) পরামিতি;
            }
            অন্য {
                _ফ্লেগস = _ ফ্ল্যাগস & ~ (ইনট) পরামিতি;
            }
            রিটার্ন _ফ্লেগস;
        }
    }

কেউ ফ্ল্যাগ কোড যুক্ত করে আমার উত্তর সম্পাদনা করেছিল, তাই সত্যই, আমি নিজে চেষ্টা করে / ব্যবহার করে নি এবং এটিকে অপসারণের বিষয়টি বিবেচনা করেছি কারণ আমি মনে করি এটির নিজের উত্তর হিসাবে এটি আরও অর্থবোধ করে। যদি আমি পরে কিছুটা সময় খুঁজে পেতে পারি তবে আমি চেষ্টা করতে পারি এবং সেই কোডটি পাশাপাশি আপনার কী আছে তা পরীক্ষা করার জন্য কিছু একসাথে রাখতে পারি এবং আপনার সমস্যার আরও ভাল সমাধানে আসতে সহায়তা করতে পারি।
স্কট

0

আপনি গতিশীলভাবে রেডিও বোতাম তৈরি ListBoxকরতে পারেন, রূপান্তর ছাড়াই এটি করতে সহায়তা করতে পারেন, বেশ সহজ।

সংক্ষিপ্ত পদক্ষেপগুলি নীচে রয়েছে: একটি তালিকাবক্স তৈরি করুন এবং তালিকাবক্সের জন্য আইটেমসোর্সকে এনাম হিসাবে সেট করুন এবং তালিকার বাক্সের MyLovelyEnumনির্বাচিত আইটেমটিকে VeryLovelyEnumসম্পত্তিতে আবদ্ধ করুন । তারপরে প্রতিটি লিস্টবক্স আইটেমের জন্য রেডিও বোতাম তৈরি করা হবে।

  • পদক্ষেপ 1 : আপনার উইন্ডো, ইউজারকন্ট্রোল বা গ্রিড ইত্যাদির জন্য স্থিতিশীল সংস্থানগুলিতে এনাম যুক্ত করুন etc.
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues"
                            ObjectType="{x:Type system:Enum}"
                            x:Key="MyLovelyEnum">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:MyLovelyEnum" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
  • পদক্ষেপ 2 : তালিকার বাক্সটি ব্যবহার করুন এবং Control Templateপ্রতিটি আইটেমকে রেডিও বোতাম হিসাবে ভিতরে স্থাপন করুন ulate
    <ListBox ItemsSource="{Binding Source={StaticResource MyLovelyEnum}}" SelectedItem="{Binding VeryLovelyEnum, Mode=TwoWay}" >
        <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <RadioButton
                                Content="{TemplateBinding ContentPresenter.Content}"
                                IsChecked="{Binding Path=IsSelected,
                                RelativeSource={RelativeSource TemplatedParent},
                                Mode=TwoWay}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Resources>
    </ListBox>

সুবিধা করুন: যদি কোনদিন আপনার enum বর্গ পরিবর্তন, উল্লেখ্য GUI (XAML ফাইল) আপডেট করার জন্য প্রয়োজন হবে না।

তথ্যসূত্র: https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.