[C#] مففم: ملزم أزرار الراديو لنموذج عرض؟


Answers

يبدو أنها ثابتة ملزمة الخاصية IsChecked في .NET 4. المشروع الذي تم كسر في VS2008 يعمل في VS2010.

Question

إديت: تم إصلاح المشكلة في .NET 4.0.

لقد حاولت ربط مجموعة من أزرار الاختيار إلى نموذج عرض باستخدام الزر IsChecked . بعد مراجعة المشاركات الأخرى، يبدو أن الخاصية IsChecked ببساطة لا يعمل. لقد وضعت معا عرضا موجزا أن يستنسخ المشكلة، والتي أدرجتها أدناه.

هنا سؤالي: هل هناك طريقة واضحة وموثوق بها لربط أزرار الراديو باستخدام مففم؟ شكر.

معلومات إضافية: الخاصية IsChecked لا يعمل لسببين:

  1. عند تحديد زر، لا يتم تعيين خصائص إيششيكيد الأزرار الأخرى في المجموعة تعيين إلى فالس.

  2. عند تحديد زر، لا يتم تعيين الخاصية إيششيكيد الخاصة بها بعد المرة الأولى التي يتم فيها تحديد الزر. أنا تخمين أن يتم الحصول على ملاحق الملزمة من قبل وف على النقرة الأولى.

المشروع التجريبي: هنا هو رمز والترميز للحصول على تجريبي بسيط أن يتكاثر المشكلة. إنشاء مشروع وف واستبدال الترميز في window1.xaml مع ما يلي:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
    <StackPanel>
        <RadioButton Content="Button A" IsChecked="{Binding Path=ButtonAIsChecked, Mode=TwoWay}" />
        <RadioButton Content="Button B" IsChecked="{Binding Path=ButtonBIsChecked, Mode=TwoWay}" />
    </StackPanel>
</Window>

استبدال التعليمات البرمجية في window1.xaml.cs مع التعليمات البرمجية التالية (هاك)، الذي يحدد نموذج العرض:

using System.Windows;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = new Window1ViewModel();
        }
    }
}

الآن إضافة التعليمات البرمجية التالية إلى المشروع كما Window1ViewModel.cs :

using System.Windows;

namespace WpfApplication1
{
    public class Window1ViewModel
    {
        private bool p_ButtonAIsChecked;

        /// <summary>
        /// Summary
        /// </summary>
        public bool ButtonAIsChecked
        {
            get { return p_ButtonAIsChecked; }
            set
            {
                p_ButtonAIsChecked = value;
                MessageBox.Show(string.Format("Button A is checked: {0}", value));
            }
        }

        private bool p_ButtonBIsChecked;

        /// <summary>
        /// Summary
        /// </summary>
        public bool ButtonBIsChecked
        {
            get { return p_ButtonBIsChecked; }
            set
            {
                p_ButtonBIsChecked = value;
                MessageBox.Show(string.Format("Button B is checked: {0}", value));
            }
        }

    }
}

لإعادة إنشاء المشكلة، قم بتشغيل التطبيق ثم انقر فوق الزر A. سيظهر مربع رسالة، قائلا أن الخاصية IsChecked الزر A تم تعيينها إلى IsChecked . الآن حدد الزر B. سيظهر مربع رسالة آخر، قائلا أن الخاصية IsChecked زر B تم تعيين إلى IsChecked ، ولكن لا يوجد مربع رسالة تشير إلى أن الخاصية IsChecked الزر A تم تعيينها إلى IsChecked - لم يتم تغيير الخاصية.

الآن انقر فوق الزر A مرة أخرى. سيتم تحديد الزر في النافذة، ولكن لن يظهر مربع رسالة - لم يتم تغيير الخاصية IsChecked . وأخيرا، انقر على الزر B مرة أخرى - نفس النتيجة. لا يتم تحديث الخاصية IsChecked على الإطلاق لأي زر بعد النقر على الزر لأول مرة.




لديك لإضافة اسم المجموعة لزر الراديو

   <StackPanel>
        <RadioButton Content="Button A" IsChecked="{Binding Path=ButtonAIsChecked, Mode=TwoWay}" GroupName="groupName" />
        <RadioButton Content="Button B" IsChecked="{Binding Path=ButtonBIsChecked, Mode=TwoWay}" GroupName="groupName" />
    </StackPanel>



هنا طريقة أخرى يمكنك أن تفعل ذلك

رأي:

<StackPanel Margin="90,328,965,389" Orientation="Horizontal">
        <RadioButton Content="Mr" Command="{Binding TitleCommand, Mode=TwoWay}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Mode=Self}, Mode=TwoWay}" GroupName="Title"/>
        <RadioButton Content="Mrs" Command="{Binding TitleCommand, Mode=TwoWay}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Mode=Self}, Mode=TwoWay}" GroupName="Title"/>
        <RadioButton Content="Ms" Command="{Binding TitleCommand, Mode=TwoWay}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Mode=Self}, Mode=TwoWay}" GroupName="Title"/>
        <RadioButton Content="Other" Command="{Binding TitleCommand, Mode=TwoWay}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Mode=Self}}" GroupName="Title"/>
        <TextBlock Text="{Binding SelectedTitle, Mode=TwoWay}"/>
    </StackPanel>

ViewModel:

 private string selectedTitle;
    public string SelectedTitle
    {
        get { return selectedTitle; }
        set
        {
            SetProperty(ref selectedTitle, value);
        }
    }

    public RelayCommand TitleCommand
    {
        get
        {
            return new RelayCommand((p) =>
            {
                selectedTitle = (string)p;
            });
        }
    }



<RadioButton  IsChecked="{Binding customer.isMaleFemale}">Male</RadioButton>
    <RadioButton IsChecked="{Binding customer.isMaleFemale,Converter=      {StaticResource GenderConvertor}}">Female</RadioButton>

أدناه هو رمز إيفالويكونفرتر

public class GenderConvertor : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(bool)value;
    }

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

هذا عمل بالنسبة لي. حتى حصلت على قيمة بيندد على كل من عرض و فيوموديل وفقا لنقر زر الاختيار. صحيح -> ذكر و خطأ -> أنثى




حل واحد هو تحديث فيوموديل لأزرار الاختيار في واضع الخصائص. عند ضبط الزر A على ترو، قم بتعيين الزر B إلى فالس.

عامل هام آخر عند ربط كائن في داتاكونتيكست هو أن الكائن يجب تنفيذ إينوتيفيبروبيرتيتشانجيد. عند تغيير أي خاصية ملزمة، يجب أن يتم تشغيل الحدث وتضمين الخاصية التي تم تغييرها. (حذف نول حذف في العينة للإيجاز.)

public class ViewModel  : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool _ButtonAChecked = true;
    public bool ButtonAChecked
    {
        get { return _ButtonAChecked; }
        set 
        { 
            _ButtonAChecked = value;
            PropertyChanged(this, new PropertyChangedEventArgs("ButtonAChecked"));
            if (value) ButtonBChecked = false;
        }
    }

    protected bool _ButtonBChecked;
    public bool ButtonBChecked
    {
        get { return _ButtonBChecked; }
        set 
        { 
            _ButtonBChecked = value; 
            PropertyChanged(this, new PropertyChangedEventArgs("ButtonBChecked"));
            if (value) ButtonAChecked = false;
        }
    }
}

تصحيح:

المشكلة هي أنه عند النقر أولا على الزر B التغييرات قيمة إيشيكيد وتغذي ملزمة من خلال، ولكن الزر A لا تتغذى من خلال حالته غير المحددة إلى الخاصية بوتوناشيكيد. عن طريق تحديث يدويا في التعليمات البرمجية سوف تحصل على تعيين خاصية بوتوناشيكيد في المرة القادمة يتم النقر فوق الزر A.