ডাব্লুপিএফ-তে বিপরীত বুলিয়ান বৈশিষ্ট্যগুলি কীভাবে আবদ্ধ করবেন?


377

আমার কাছে যা আছে তা হল একটি IsReadOnlyসম্পত্তি has যদি এই সম্পত্তিটি সত্য হয় তবে আমি IsEnabledসম্পত্তিটিকে একটি বোতামে সেট করতে চাই , (উদাহরণস্বরূপ), মিথ্যা to

আমি বিশ্বাস করতে চাই যে আমি এটি যতটা সহজেই করতে পারি IsEnabled="{Binding Path=!IsReadOnly}"তবে ডাব্লুপিএফ দিয়ে উড়ে না।

আমি কি সমস্ত স্টাইল সেটিংসের মধ্য দিয়ে যেতে পেরেছি? কেবল একটি বিলের বিপরীতে অন্য একটি সেটকে সেট করার মতো সহজ জিনিসের জন্য খুব স্পষ্ট মনে হয়।

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
                <Setter Property="IsEnabled" Value="True" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>

সম্পর্কিত: stackoverflow.com/questions/534575/...
UuDdLrLrSs

এহ এমএস ভাল কাজ করুন তবে এটি অসম্পূর্ণ
ব্যবহারকারীর 1005462

উত্তর:


488

আপনি একটি ভ্যালু কনভার্টর ব্যবহার করতে পারেন যা আপনার জন্য একটি বুল সম্পত্তি বিপরীত করে।

XAML:

IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"

কনভার্টার:

[ValueConversion(typeof(bool), typeof(bool))]
    public class InverseBooleanConverter: IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(bool))
                throw new InvalidOperationException("The target must be a boolean");

            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }

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

17
আপনার নিজের যুক্তি দ্বারা, আইএমএইচও রূপান্তর সমাধান দীর্ঘমেয়াদে আরও ভাল: আপনাকে কেবল একবার কনভার্টারটি লিখতে হবে এবং তারপরে আপনি এটিকে বারবার পুনরায় ব্যবহার করতে পারবেন। আপনি যদি নতুন সম্পত্তির জন্য যান তবে আপনাকে এটি প্রয়োজন প্রতিটি শ্রেণিতে এটি আবার লিখতে হবে ...
টমাস লেভস্ক

51
আমি একই পন্থাটি ব্যবহার করছি ... তবে এটি পান্ড সাদ তৈরি করে ... = (
সর্বোচ্চ গ্যালকিন

27
তুলনায় !, এটি কিছু দীর্ঘ-বাতাসযুক্ত কোড ... লোকেরা "দুর্বল ডিজাইনার" থেকে তাদের "কোড" বলে মনে করেন তা আলাদা করার জন্য পাগলামি প্রচেষ্টায় যান। আমি কোডার এবং ডিজাইনার উভয়েই অতিরিক্ত অতিরিক্ত বেদনাদায়ক
রোমান স্টারকভ

10
আমার সহ অনেক লোক এটিকে ওভার ইঞ্জিনিয়ারিংয়ের একটি প্রধান উদাহরণ হিসাবে বিবেচনা করবেন। আমি নীচের পল আলেকজান্ডার পোস্টের মতো একটি উল্টানো সম্পত্তি ব্যবহার করার পরামর্শ দিচ্ছি।
খ্রিস্টান ওয়েস্টম্যান 14'14

99

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


5
আমি এই পন্থাটি ব্যবহার করে একই সমস্যার সমাধান করেছি এবং আমি সম্মত হচ্ছি যে কেবল এটি আরও মার্জিত নয়, একটি রূপান্তরকারী ব্যবহারের চেয়েও অনেক বেশি রক্ষণাবেক্ষণযোগ্য।
আলিম্বাদা

28
আমি মতানৈক্য করব যে এই পদ্ধতির মান রূপান্তরকারী চেয়ে ভাল। আপনার বেশ কয়েকটি নটপ্রোপার্টি উদাহরণগুলির প্রয়োজন হলে এটি আরও কোড তৈরি করে।
থিরু

25
এমভিভিএম কোড লেখার বিষয়ে নয়, এটি ঘোষণামূলকভাবে সমস্যাগুলি সমাধান করার বিষয়ে। তা করার জন্য, রূপান্তরকারী হয় সঠিক সমাধান।
জেফ

14
এই সমাধানটির সমস্যাটি হ'ল যদি আপনার কাছে 100 টি অবজেক্ট থাকে তবে আপনাকে সমস্ত 100 টি অবজেক্টে একটি ইসনট্রিডঅনলি সম্পত্তি যুক্ত করতে হবে। এই সম্পত্তিটি নির্ভরতাপ্রাপ্ত হতে হবে। এটি সমস্ত 100 টি অবজেক্টে বা কোডের 1000 লাইনগুলিতে কোডের প্রায় 10 লাইন যুক্ত করে। রূপান্তরকারী কোড 20 লাইন হয়। 1000 লাইন বা 20 লাইন। আপনি যা পছন্দ করে নিন হবে?
ছড়া

8
এর জন্য একটি প্রচলিত প্রবাদ আছে: এটি একবার করুন, একবার করুন এবং তারপরে স্বয়ংক্রিয় করুন। সন্দেহজনকভাবে, আমি এই উত্তরটি কোনও প্রকল্পে প্রথমবারের মতো ব্যবহার করব এবং তারপরে যদি জিনিসগুলি বাড়তে থাকে তবে আমি স্বীকৃত উত্তরটি ব্যবহার করব। তবে কনভার্টর স্নিপেট প্রাক-তৈরি থাকায় এটি ব্যবহার করা সহজতর হতে পারে।
হেলটনবাইকার

71

স্ট্যান্ডার্ড বাঁধাইয়ের সাথে আপনার এমন রূপান্তরকারী ব্যবহার করা দরকার যা দেখতে খুব কম বাতাস দেখায়। সুতরাং, আমি আপনাকে আমার প্রকল্প ক্যালব্যান্ড বাইন্ডিংটি দেখার পরামর্শ দিই , যা এই সমস্যাটি সমাধানের জন্য বিশেষভাবে তৈরি করা হয়েছিল এবং কিছু অন্যান্য। উন্নত বাঁধাইয়ের সাহায্যে আপনি সরাসরি এক্সএএমএলে বহু উত্সের বৈশিষ্ট্য সহ অভিব্যক্তি লিখতে পারেন। বলুন, আপনি এমন কিছু লিখতে পারেন:

<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />

অথবা

<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>

অথবা

<Label Content="{c:Binding A+B+C }" />

অথবা

<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />

যেখানে এ, বি, সি, ইসচেকড - ভিউমোডেলের বৈশিষ্ট্য এবং এটি সঠিকভাবে কাজ করবে


6
যদিও কুইকনভার্টারটি আরও শক্তিশালী, আমি ক্যালসিবাইন্ডিং মোডটি পঠনযোগ্য - ব্যবহারযোগ্য find
xmedeko

3
এটা খুব ভালো একটা যন্ত্র। আমি আশা করি এটি 5 বছর আগে বিদ্যমান ছিল!
jug1es

উজ্জ্বল সরঞ্জাম, তবে শৈলীতে পড়ে। <Setter.Value><cb:Binding Path="!IsReadOnly" /></Setter.Value>পায় একটি 'বাঁধাই' বৈধ Setter.Value 'কম্পাইল সময় এরর জন্য
mcalex

21

আমি https://quickconverter.codeplex.com/ ব্যবহার করার পরামর্শ দেব

বুলিয়ান উল্টানো তত সহজ: <Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />

এটি সাধারণত রূপান্তরকারীদের লেখার জন্য প্রয়োজনীয় সময়ের গতি।


18
কাউকে -১ দেওয়ার সময় কেন তা ব্যাখ্যা করে ভালো লাগবে।
Noxxys 10

16

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

public class InvertableBool
{
    private bool value = false;

    public bool Value { get { return value; } }
    public bool Invert { get { return !value; } }

    public InvertableBool(bool b)
    {
        value = b;
    }

    public static implicit operator InvertableBool(bool b)
    {
        return new InvertableBool(b);
    }

    public static implicit operator bool(InvertableBool b)
    {
        return b.value;
    }

}

আপনার প্রকল্পে কেবলমাত্র পরিবর্তনগুলি হ'ল আপনি যে সম্পত্তিটিকে বিপরীত করতে চান তা বুলের পরিবর্তে ফেরত দেওয়া

    public InvertableBool IsActive 
    { 
        get 
        { 
            return true; 
        } 
    }

এবং এক্সএএমএল পোস্টফিক্সে মান বা বিপরীতগুলির সাথে বাইন্ডিং

IsEnabled="{Binding IsActive.Value}"

IsEnabled="{Binding IsActive.Invert}"

1
খারাপ দিকটি হ'ল আপনাকে এমন সমস্ত কোড পরিবর্তন করতে হবে যা একে অন্য boolটাইপ এক্সপ্রেশন / ভেরিয়েবলগুলির সাথে তুলনা করে / নির্ধারিত করে এমনকি বিপরীত মানটি উল্লেখ না করে। পরিবর্তে আমি এর সাথে একটি "নয়" এক্সটেনশন পদ্ধতি যুক্ত করব Boolean Struct
টম

1
ডোহ! কিছু মনে করো না. হতে হয় ভুলে গেছেন Propertyবনাম Methodজন্য Binding। আমার "ডাউনসাইড" স্টেটমেন্টটি এখনও প্রযোজ্য। বিটিডব্লিউ, 'বুলিয়ান` "নয়" এক্সটেনশন পদ্ধতি "এড়ানোর জন্য এখনও কার্যকর! অপারেটর যা সহজে মিস যখন এটা (হিসাবে প্রায়ই ক্ষেত্রে দেখা যায়) অক্ষর পাশে এমবেড করা হয় এটি মত চেহারা (অর্থাত এক / আরো "(" 's এবং "L"' s এবং "আমি" 'গুলি)।
টম

10

এই একটিও nullaable bools জন্য কাজ করে।

 [ValueConversion(typeof(bool?), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (targetType != typeof(bool?))
        {
            throw new InvalidOperationException("The target must be a nullable boolean");
        }
        bool? b = (bool?)value;
        return b.HasValue && !b.Value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(value as bool?);
    }

    #endregion
}

4

আপনার ভিউ মডেলে আরও একটি সম্পত্তি যুক্ত করুন, যা বিপরীত মান ফিরে আসবে। এবং এটি বোতামে বাঁধুন। ভালো লেগেছে;

মডেল দেখুন:

public bool IsNotReadOnly{get{return !IsReadOnly;}}

এক্সএএমএলে:

IsEnabled="{Binding IsNotReadOnly"}

1
দুর্দান্ত উত্তর। একটি জিনিস যোগ করার জন্য এটি ব্যবহার করে আপনি ইস্রনডনালি সম্পত্তি ইসটার জন্য কেবল ইসনট্রইডঅনলাইটির জন্য প্রপার্টি চেঞ্জড ইভেন্টটি আরও ভাল করে তুলুন। এটির সাহায্যে আপনি নিশ্চিত হয়ে যাবেন যে ইউআই সঠিকভাবে আপডেট হয়েছে।
মুহান্নাদ

এটি সবচেয়ে সহজ হিসাবে গ্রহণযোগ্য উত্তর হওয়া উচিত।
গাবনাইম

2

এটি এক্সএএমএল-এর সাথে প্রাসঙ্গিক কিনা তা জানেন না, তবে আমার সাধারণ উইন্ডোজ অ্যাপে আমি নিজেই বাইন্ডিং তৈরি করে একটি ফর্ম্যাট ইভেন্ট হ্যান্ডলার যুক্ত করেছি।

public FormMain() {
  InitializeComponent();

  Binding argBinding = new Binding("Enabled", uxCheckBoxArgsNull, "Checked", false, DataSourceUpdateMode.OnPropertyChanged);
  argBinding.Format += new ConvertEventHandler(Binding_Format_BooleanInverse);
  uxTextBoxArgs.DataBindings.Add(argBinding);
}

void Binding_Format_BooleanInverse(object sender, ConvertEventArgs e) {
  bool boolValue = (bool)e.Value;
  e.Value = !boolValue;
}

1
রূপান্তরকারী পদ্ধতির চেয়ে দেখতে অনেকটা একই। Formatএবং Parseউইনফোর্ডস বাইন্ডিংয়ের ইভেন্টগুলি ডাব্লুপিএফ রূপান্তরকের প্রায় সমতুল্য।
আলেজান্দ্রো

2

আমার একটি বিপরীত সমস্যা ছিল, তবে একটি ঝরঝরে সমাধান।

অনুপ্রেরণা ছিল যে এক্সএএমএল ডিজাইনার একটি খালি নিয়ন্ত্রণ উদাহরণ দেখান যেমন কোনও ডাটাকন্টেক্সট / নেই যখন MyValues ডেটাকন্টেক্সট (আইটেমসোর্স) না থাকলে।

প্রাথমিক কোড: খালি থাকাকালীন নিয়ন্ত্রণ লুকানMyValues । উন্নত কোড: কখন নিয়ন্ত্রণ প্রদর্শন করুনMyValues শূন্য বা খালি না ।

অবশ্যই সমস্যাটি হল কীভাবে '1 বা ততোধিক আইটেম' প্রকাশ করা যায় যা 0 টি আইটেমের বিপরীত।

<ListBox ItemsSource={Binding MyValues}">
  <ListBox.Style x:Uid="F404D7B2-B7D3-11E7-A5A7-97680265A416">
    <Style TargetType="{x:Type ListBox}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding MyValues.Count}">
          <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.Style>
</ListBox>

আমি এটি যুক্ত করে সমাধান করেছি:

<DataTrigger Binding="{Binding MyValues.Count, FallbackValue=0, TargetNullValue=0}">

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


2

💡। নেট কোর সলিউশন 💡

নাল পরিস্থিতি পরিচালনা করে এবং একটি ব্যতিক্রম ছুঁড়ে না, তবে trueকোনও মান উপস্থাপন না করা হলে ফিরে আসে ; অন্যথায় ইনপুটযুক্ত বুলিয়ান নেয় এবং বিপরীত হয়।

public class BooleanToReverseConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     => !(bool?) value ?? true;

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     => !(value as bool?);
}

Xaml

IsEnabled="{Binding IsSuccess Converter={StaticResource BooleanToReverseConverter}}"

App.Xaml আমি আমার সমস্ত রূপান্তরকৃত স্ট্যাটিকসটি অ্যাপ.এক্সএএমএল ফাইলটিতে রাখতে চাই যাতে প্রকল্পের উইন্ডোজ / পৃষ্ঠাগুলি / নিয়ন্ত্রণগুলিতে আমার সেগুলি পুনরায় ঘোষণা করতে হবে না।

<Application.Resources>
    <converters:BooleanToReverseConverter x:Key="BooleanToReverseConverter"/>
    <local:FauxVM x:Key="VM" />
</Application.Resources>

পরিষ্কার converters:হওয়া প্রকৃত শ্রেণীর প্রয়োগের নামকরণ ( xmlns:converters="clr-namespace:ProvingGround.Converters")।


1

@ পলের উত্তর অনুসরণ করে আমি ভিউমোডেলে নিম্নলিখিতগুলি লিখেছি:

public bool ShowAtView { get; set; }
public bool InvShowAtView { get { return !ShowAtView; } }

আমি আশা করি এখানে একটি স্নিপেট রাখলে কাউকে সাহায্য করবে, সম্ভবত আমার মতো নবাগত।
এবং যদি কোনও ভুল হয় তবে দয়া করে আমাকে জানান!

বিটিডাব্লু, আমি @ হেল্টনবাইকার মন্তব্যের সাথেও একমত - আপনার যদি এটির চেয়ে 3 বারের বেশি ব্যবহার না করতে হয় তবে এটি অবশ্যই সঠিক পন্থা ...


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

1

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

private bool _isSearching;
public bool IsSearching
{
    get { return !_isSearching; }
    set
    {
        if(_isSearching != value)
        {
            _isSearching = value;
            OnPropertyChanged("IsSearching");
        }
    }
}

public CityViewModel()
{
    LoadedCommand = new DelegateCommandAsync(LoadCity, LoadCanExecute);
}

private async Task LoadCity(object pArg)
{
    IsSearching = true;

    //**Do your searching task here**

    IsSearching = false;
}

private bool LoadCanExecute(object pArg)
{
    return IsSearching;
}

তারপরে কম্বোবক্সের জন্য আমি এটি সরাসরি অনুসন্ধানের সাথে আবদ্ধ করতে পারি:

<ComboBox ItemsSource="{Binding Cities}" IsEnabled="{Binding IsSearching}" DisplayMemberPath="City" />

0

আমি @ ওফাইমের মতো একটি অনুরূপ পন্থা ব্যবহার করি

private bool jobSaved = true;
private bool JobSaved    
{ 
    get => jobSaved; 
    set
    {
        if (value == jobSaved) return;
        jobSaved = value;

        OnPropertyChanged();
        OnPropertyChanged("EnableSaveButton");
    }
}

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