具有数据绑定的TriStateRadio用户控件 [英] TriStateRadio User Control with DataBinding

查看:65
本文介绍了具有数据绑定的TriStateRadio用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好.
我正在尝试使用三个单选按钮编写简单的用户控件,这些单选按钮支持将数据绑定到bit(或bool)字段.单选按钮的三个值分别是:是"表示true,否"表示false,"n/d"表示null.对于绑定,我尝试使用[System.ComponentModel.DefaultBindingProperty("Checked")]属性,但它仅以一种方式工作(从数据源读取),或者似乎根本不更改任何内容.
第二件事是使用INotifyPropertyChange接口来通知我的bool-binded属性已更改,因此控件应更新接口.但是我不太明白,如何使用PropertyChangedEventHandler(我缺少一些委托吗?)
下面是我控件的代码(很明显,除了Designer之外).
请问有人可以打我一下,我在这里想念什么吗?

Hello folks.
I''m trying to write simple user control with three radio buttons that support data binding to bit (or bool) field. The three values for radio buttons are: "Yes" for true, "No" for false and "n/d" for null. For binding I''ve tried to use [System.ComponentModel.DefaultBindingProperty("Checked")] attribute but it''s working one way only (reading from data source), or seems not to change anything at all.
The second thing is using INotifyPropertyChange interface for notification that my bool-binded property has changed, so control should update interface. But I don''t quite understand, how to employ PropertyChangedEventHandler (am I missing some delegate?)
Below is the code for my control (except from designer, which is obvious).
Can anyone, please, just hit me with a hint, what am I missing here?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace TriStateRadioControlLibrary
{
    [System.ComponentModel.DefaultBindingProperty("Checked")] //simple binding attribute
    public partial class TriStateRadio : UserControl, INotifyPropertyChanged
    {
        // properties for external access
        public String TextTrueRadio { get { return radioButton1.Text; } set { radioButton1.Text = value; } }
        public String TextFalseRadio { get { return radioButton2.Text; } set { radioButton2.Text = value; } }
        public String TextNullRadio { get { return radioButton3.Text; } set { radioButton3.Text = value; } }

        public Nullable<bool> _checked;
        // binding property
        public Nullable<bool> Checked
        {
            get { return _checked; }
            set
            {
                if (value != _checked)
                {
                    _checked = value;
                    OnPropertyChanged("Checked");
                }
            }
        }

        private void CheckChanged() //instead of using stupid events, but working one way only
        {
            switch (_checked)
            {
                case true:
                    radioButton1.Checked = true;
                    break;
                case false:
                    radioButton2.Checked = true;
                    break;
                case null:
                    radioButton3.Checked = true;
                    break;
                default:
                    throw new Exception("Error selecting TriStateRadio state!");
                    //break;
            }
        }



        public TriStateRadio()
        {
            InitializeComponent();
        }

        //events for changing between radio buttons
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton1.Checked == true)
            {
                this.Checked = true;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton2.Checked == true)
            {
                this.Checked = false;
            }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton3.Checked == true)
            {
                this.Checked = null;
            }
        }


        #region PropertyChangeNotification
        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, e);
        }

        public void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

    }
}




我已经进行了数小时的谷歌搜索和调试,没有任何效果:(




I''ve been googling and debugging for hours now with no effect :(

推荐答案

好,我已经解决了两个问题-绑定值未保存到数据源并且没有更新接口.我来的解决方案很简单,但是我仍然不明白INotifyPropertyChange接口是如何工作的.在完整的工作方案下,还有另外两种方法.

OK, I''ve solved both of my problems - with binded value not saved to data source and with not updating interface. The solution which I came is rather simple, but I still don''t understand how INotifyPropertyChange interface is working. Below full, working solution with additional two methods.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace TriStateRadioControlLibrary
{
    [System.ComponentModel.DefaultBindingProperty("Checked")] //simple binding attribute
    public partial class TriStateRadio : UserControl, INotifyPropertyChanged
    {
        // properties for external access
        public String TextTrueRadio { get { return radioButton1.Text; } set { radioButton1.Text = value; } }
        public String TextFalseRadio { get { return radioButton2.Text; } set { radioButton2.Text = value; } }
        public String TextNullRadio { get { return radioButton3.Text; } set { radioButton3.Text = value; } }

        public Nullable<bool> _checked;
        // binding property
        public Nullable<bool> Checked
        {
            get { return _checked; }
            set
            {
                if (value != _checked)
                {
                    _checked = value;
                    OnPropertyChanged("Checked");
                }
            }
        }

        private void CheckChanged() //update bool field
        {
            switch (_checked)
            {
                case true:
                    radioButton1.Checked = true;
                    break;
                case false:
                    radioButton2.Checked = true;
                    break;
                case null:
                    radioButton3.Checked = true;
                    break;
                default:
                    throw new Exception("Error selecting TriStateRadio state!");
                    //break;
            }
        }



        public TriStateRadio()
        {
            InitializeComponent();
        }

        //events for changing between radio buttons
        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton1.Checked == true)
            {
                this.Checked = true;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton2.Checked == true)
            {
                this.Checked = false;
            }
        }

        private void radioButton3_CheckedChanged(object sender, EventArgs e)
        {
            if (this.radioButton3.Checked == true)
            {
                this.Checked = null;
            }
        }


        #region PropertyChangeNotification
        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, e);
        }

        public void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

        
        public event PropertyChangedEventHandler PropertyChanged;
        
        #endregion

        //necesary to update control interface when loaded
        private void TriStateRadio_Load(object sender, EventArgs e)
        {
            PropertyChanged += new PropertyChangedEventHandler(TriStateRadio_PropertyChanged);
            CheckChanged();
        }

        void TriStateRadio_PropertyChanged(object sender, EventArgs e)
        {
            CheckChanged(); //this can be used with EventArgs to detect which property has actually changed
        }

    }
}


正如我所想,那是失踪的代表:)


As I thought, it was the missing delegate :)


这篇关于具有数据绑定的TriStateRadio用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆