كيف يمكنني استخدام ربط البيانات مع أزرار الاختيار Windows Forms؟

StackOverflow https://stackoverflow.com/questions/344964

سؤال

لدي حقل ثنائي في قاعدة البيانات الخاصة بي يصعب وصفه في واجهة المستخدم باستخدام مربع اختيار واحد من النوع "هل XXXX؟".أفضل استخدام زوج من أزرار الاختيار (على سبيل المثال."افعلها بطريقة Foo" و"افعلها بطريقة Bar")، ولكن في الوقت الحالي جميع الحقول الأخرى في النموذج الخاص بي مرتبطة بالبيانات بكائن أعمال.أرغب في ربط زوج أزرار الاختيار بكائن الأعمال أيضًا، لكن لم أتوصل إلى طريقة جيدة للقيام بذلك بعد.يمكنني ربط أحد الأزرار بالحقل، بحيث يتم تعيين الحقل على "صحيح" إذا تم تحديد الزر، ولكن أثناء تحديد الزر الآخر يتم إلغاء تحديد الزر الأول (أي، يتم إقران زري الاختيار بشكل صحيح )، لا يتم تحديث قيمة الحقل لتعكس ذلك.

أود أن أكون قادرًا على القول

button1.DataBindings.Add(new Binding("checked", source, "useFoo"));
button2.DataBindings.Add(new Binding("checked", source, "!useFoo"));

ولكن أنا متأكد من أن ذلك سوف يرمي عندما يتم تشغيله.هل هناك طريقة أسهل، أم يجب أن أفكر أكثر في كيفية صياغة مربع اختيار واحد؟لا أريد إضافة وظائف إضافية للتعامل مع شيء تافه هذا ...

الوقت المتوقع للوصول:اقترح أحد المعلقين النظر في القائمة المنسدلة (ComboBox).لقد فكرت في هذا، ولكن كيف يمكنني ربط البيانات بحقل منطقي في قاعدة بيانات/خاصية في كائن أعمال؟إذا قمت بربط SelectedItem بخاصية useFoo، فما الذي سيحدث في مجموعة العناصر؟هل يجب أن أضيف فقط "True" و"False"، أو هل يمكنني بطريقة ما إضافة كائن زوج المفتاح/القيمة الذي يربط العنصر المعروض ("Use Foo"/"Do Not Use Foo") بالقيمة المنطقية خلفه؟أواجه مشكلة في العثور على مستندات حول هذا الموضوع.


حول الجواب:كان الحل الذي انتهيت من استخدامه يتضمن تعديل كائن الأعمال - الفكرة الأساسية مشابهة جدًا للفكرة التي نشرها Gurge، لكنني توصلت إليها بشكل منفصل قبل أن أقرأ رده.باختصار، أضفت خاصية منفصلة تعود ببساطة !useFoo.زر اختيار واحد مرتبط بـ source.UseFoo, ، والآخر ملزم به source.UseBar (اسم العقار الجديد).من المهم التأكد من أن الخاصية الجديدة تحتوي على حروف الحروف والحرف، وإلا فسوف ينتهي بك الأمر إلى سلوك غريب حقًا.

هل كانت مفيدة؟

المحلول

ولقد وجدت طريقة للقيام بذلك باستخدام مجموعة البيانات / DataTable و.

وأنا جعل عمود محسوب في DataTable مع IIF(Foo=true, false, true) التعبير. دعونا نسمي ذلك Bar العمود.

وBar هو من نوع منطقية. الآن يمكنك ربط RadioButton.Checked إلى Foo واحد لBar.

لتحصل على فحص Bar / إلغاء لنشر العودة إلى Foo يجب أن تذهب إلى رمز DataTable ولدت وإضافة سطر واحد، كان آخرها في هذه العينة:

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public bool Bar {
    get {
        try {
            return ((bool)(this[this.tableradio.BarColumn]));
        }
        catch (global::System.InvalidCastException e) {
            throw new global::System.Data.StrongTypingException("The value for column \'Bar\' in table \'radio\' is DBNull.", e);
        }
    }
    set {
        this[this.tableradio.BarColumn] = value;
        this[this.tableradio.FooColumn] = !value;
    }
}

نصائح أخرى

  1. ربط RadioButton المرتبطة مباشرة بالقيمة المنطقية الخاصة بك (أي يتم تحديدها عندما تكون القيمة true).
  2. أضف معالج الأحداث إلى CheckedChanged الحدث على هذا RadioButton يبدو كما يلي:

    private void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        foreach (Binding b in ((Control)sender).DataBindings)
            b.WriteValue();
    }
    

إذا الكائن عملك تنفذ INotifyPropertyChanged (وهو ما يجعل أجمل عمل ملزم)، يمكنك إضافة التعليمات البرمجية التالية إلى واجهة مرئية حيث BO هو كائن عملك وأعلن الأساسية WithEvents وBO.Value هو ملك منطقية كنت ترغب في ربط.

Public Property NotValue() As Boolean
    Get
        Return Not BO.Value
    End Get
    Set(ByVal value As Boolean)
        BO.Value = Not value
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue"))
    End Set
End Property


Private Sub BO_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles BO.PropertyChanged
    If e.PropertyName = "Value" Then
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue"))
    End If
End Sub

والارتباطات التالية سوف عقف أزرار الاختيار.

RBTrue.DataBindings.Add(New Binding("Checked", Me.BO, "Value", False, DataSourceUpdateMode.OnPropertyChanged))
RBFalse.DataBindings.Add(New Binding("Checked", Me, "NotValue", False, DataSourceUpdateMode.OnPropertyChanged))

ويجب على واجهة بصرية أيضا تنفيذ INotifyPropertyChanged. هذا الأسلوب يعمل في كلا الاتجاهين: يتم تحديث القيمة الأصلية إذا كانت التغييرات واجهة وإذا تغير القيمة الأصلية واجهة سيتم تحديث بشكل صحيح

وجئت عبر نفس المشكلة، وتبين أنه من الممكن فعلا مع ربط البيانات القياسية:

button1.DataBindings.Add(new Binding("checked", source, "useFoo", false, DataSourceUpdateMode.OnPropertyChanged);
// no need to databind button 2, since button1.checked 
// is set to false when button2 is checked

وافتراضيا، يتم تعيين DataSourceUpdateMode إلى OnValidation. عن طريق وضع لOnPropertyChanged، يتم نشر التغيير على الفور إلى كائن ربط بيانات.

وبلدي كائن الأعمال تنفذ INotifyPropertyChanged؛

وعن طريق اختبار هذا الحل، وجدت أن بلدي الحدث OnPropertyChanged أقيل مرتين عندما كنت النقر button2. لمنع هذا، تعيين ببساطة

button1.CausesValidation = false;
button2.CausesValidation = false;

وكما هو موضح هنا: يسبب PropertyChanged الحصول على النار مرتين

هل يدويا في التعليمات البرمجية. عند تحميل النموذج تعيين أزرار الراديو الخاص بك وفقا لقاعدة البيانات الخاصة بك. عند الضغط على "حفظ" مخزن زر دي دولة كما يحلو لك. هذا المثال بتخزين أجهزة الراديو كما حقول بت في قاعدة البيانات.

        // Load radio state
        radioButton1.Checked = ((myModel)myBindingSource.DataSource).boolOption1;
        radioButton2.Checked = ((myModel)myBindingSource.DataSource).boolOption2;

-

        // Save radio state
        ((myModel)myBindingSource.DataSource).boolOption1 = radioButton1.Checked;
        ((myModel)myBindingSource.DataSource).boolOption2 = radioButton2.Checked;

وحاولت سحب العناصر من لوحة "مصادر البيانات" في Visual Studio 2015 عندما كنت تعرف أزرار بصفتي القيم المنطقية في الجدول ولكن هناك مشاكل مع القيم المنطقية لا يتم تحديثه إلى false عند تحديد زر خيار آخر. عند تغيير "causesValidation" لradiobuttons كاذبة دون رادع تلقائيا عندما قفز بين حقول إدخال النص الأخرى.

هل ينبغي أن يكون فقط لربط واحدة من الضوابط ما دمت التأكد من أنها في نفس المجموعة.

هل يمكن أن نعتبر أيضا المنسدلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top