这些是在UserControl中实现简单数据绑定的所有要求
本文关键字:数据绑定 简单 实现 UserControl | 更新日期: 2023-09-27 18:27:28
为了创建一个支持简单数据绑定的自定义控件,我遵循了微软在这里报告的说明,并且在我发现它们不完整后不久。实现DefaultBindingProperty
属性是不够的,您似乎需要控制(i)实现INotifyPropertyChanged
或公开名为<propertyname>Changed
的事件,如这里所解释的。
尽管如此,我下面的代码(实际上是它的一个非常简化的版本)仍然不起作用,我已经为此挣扎了将近一天。我的控制是:
[DefaultBindingProperty("Value")]
public partial class MyUserControl : UserControl
{
NumericUpDown upDown;
public MyUserControl()
{
InitializeComponent();
upDown = new NumericUpDown() { Minimum = 0, Maximum = 100, Dock = DockStyle.Fill };
Controls.Add(upDown);
upDown.ValueChanged += control_ValueChanged;
}
[Bindable(true)]
public double Value
{
get { return (double)upDown.Value; }
set { upDown.Value = (decimal)value; }
}
private void control_ValueChanged(object sender, EventArgs e)
{
if (ValueChanged != null)
ValueChanged(this, e);
}
public event EventHandler<EventArgs> ValueChanged;
}
和我的测试表格:
public partial class Form1 : Form
{
MyUserControl myUserControl;
BindingSource source;
MyClass myClass;
public Form1()
{
InitializeComponent();
source = new BindingSource();
myClass = new MyClass() { Amount = 30 };
source.DataSource = new[] { myClass };
myUserControl = new MyUserControl();
Controls.Add(myUserControl);
myUserControl.DataBindings.Add("Value", source, "Amount", false, DataSourceUpdateMode.OnPropertyChanged);
}
}
public class MyClass
{
int amount;
public int Amount
{
get { return amount; }
set
{
amount = value;
MessageBox.Show("New amount: " + amount);
}
}
}
在更改NumericUpDown
中的值时,不会触发代码末尾的消息框。还有我遗漏的另一条信息吗?我在这里做错了什么?
似乎需要让控件实现INotifyPropertyChanged或公开名为<propertyName>更改如下。
这些是实现数据源时的选项。对于自定义控件,唯一的选择是后者,因为基本控件已经在使用该模式,并且实现INotifyPropertyChanged
将破坏它,因为正如的一个注释所述
为了在绑定客户端和数据源之间的绑定中发生更改通知,您的绑定数据源类型应实现INotifyPropertyChanged接口(首选),或者您可以为绑定类型提供propertyNameChanged事件,但不应同时执行这两种操作。
所以你正确地使用了PropertyNameChanged
模式(或者至少尝试过:)
还有我遗漏的另一条信息吗?我在这里做错了什么?
以下是一些相关链接-Windows窗体数据绑定中的更改通知和如何:应用PropertyNameChanged模式,但您缺少的是PropertyNameChanged
模式到底是什么,不幸的是,文档中的任何地方似乎都没有解释,关键是,除了特别命名的事件外,它还需要该事件的特定类型,更确切地说是EventHandler
类型。我想现在你看到问题了——你已经使用了EventHandler<EventArgs>
。方法签名是相同的,但对于Action<object, EvenetArgs>
可以说是相同的。EventHandler<TEventArgs>
现在是推荐的,但请记住,在引入数据绑定时它并不存在。等等
矮子,把这条线换成
public event EventHandler<EventArgs> ValueChanged;
至
public event EventHandler ValueChanged;
一切都会按预期进行。