问题描述
大家好.
我正在尝试使用三个单选按钮编写简单的用户控件,这些单选按钮支持将数据绑定到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 :(
推荐答案
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用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!