积极答复者
数据绑定的问题

问题
-
我刚学WPF,刚了解了数据绑定,现在想实现一些比较复杂的功能,示例在下面:
'--------------------源对象 Public bigobj As New Big '--------------------数据 Public Class Big Private _d1 As Little1 Private _d2 As Little2 Public Property D1() As Little1 Get Return _d1 End Get Set(ByVal value As Little1) _d1 = value End Set End Property Public Property D2() As Little2 Get Return _d2 End Get Set(ByVal value As Little2) _d2 = value End Set End Property End Class Public Class Little1 Private _x(5) As Integer Public Property X(ByVal i As Integer) As Integer Get Return _x(i) End Get Set(ByVal value As Integer) _x(i) = value '???? End Set End Property End Class Public Class Little2 Private _y As Integer Public Property Y() As Integer Get Return _y End Get Set(ByVal value As Integer) _y = value '???? End Set End Property End Class '--------------------控件 Public Class MyCanvas Inherits Canvas Private Tx(5), Ty As TextBox Public Sub New() CreateBinding() End Sub Public Sub CreateBinding() Dim bind As New Binding() '???? End Sub End Class
我想在加载 MyCanvas 实例的时候创建绑定,将 Tx(0-5) 绑定到 bigobj.D1.X(0-5),Ty 绑定到 bigobj.D2.Y,只用那一个 bind 对象来完成,三个问号处代码怎么写呢?谢谢了(MSDN 上面的数据绑定示例是绑定元数据,我照着写无法实现绑定对象成员当中的数据成员,因此请帮我完成那三处代码)
答案
-
楼主你好,
-->只用那一个 bind 对象来完成,三个问号处代码怎么写呢?谢谢了(MSDN 上面的数据绑定示例是绑定元数据,我照着写无法实现绑定对象成员当中的数据成员,因此请帮我完成那三处代码.
我想你要实现的binding功能并不是在三个问号中实现的,而是在CreateBinding方法中实现的,那三个属情访问器(Set)中你只要像一般的设置值就可以了。并且我想你这里要实现的是多个binding,一个binding实例并不可行,你可以试一下我下面提供的代码段:
public void CreateBinding(){
for (int i = 0; i <Tx.Length; i++)
{
Binding bind = new Binding();
bind.Path = new PropertyPath(".");
//make the X property return _x, not _x[i];
bind.Source = new List<int> { new Big().D1.X[i] };
Tx[i].SetBinding(TextBox.TextProperty, bind);
}
}
如有疑问,请继续回复.
谢谢.
Jim Zhou -MSFT- 已标记为答案 Jim Zhou - MSFTModerator 2009年11月11日 8:44
全部回复
-
楼主你好,
-->只用那一个 bind 对象来完成,三个问号处代码怎么写呢?谢谢了(MSDN 上面的数据绑定示例是绑定元数据,我照着写无法实现绑定对象成员当中的数据成员,因此请帮我完成那三处代码.
我想你要实现的binding功能并不是在三个问号中实现的,而是在CreateBinding方法中实现的,那三个属情访问器(Set)中你只要像一般的设置值就可以了。并且我想你这里要实现的是多个binding,一个binding实例并不可行,你可以试一下我下面提供的代码段:
public void CreateBinding(){
for (int i = 0; i <Tx.Length; i++)
{
Binding bind = new Binding();
bind.Path = new PropertyPath(".");
//make the X property return _x, not _x[i];
bind.Source = new List<int> { new Big().D1.X[i] };
Tx[i].SetBinding(TextBox.TextProperty, bind);
}
}
如有疑问,请继续回复.
谢谢.
Jim Zhou -MSFT- 已标记为答案 Jim Zhou - MSFTModerator 2009年11月11日 8:44
-
调试了一下午,晚上才发现原来 Friend 属性是不能参与绑定的…………
bind.Source = new List { new Big().D1.X[i] };
一句我在 VB.NET 里面写成
bind.Source = New List(Of Int32) {New Big.D1.X(i)}
语法是错的,请教一下应该怎么写……如果我直接把它写成
bind.Source = Big.D1.X(i) 结果效果就会变成 OneTime 绑定,该怎么做呢?谢谢答疑
另外就是个不成问题的小问题,采用这种方法需要设置数组属性 Property X As Int32(),而这样设置会引起警告错CA1819“属性不应返回数组”。虽然不影响运行,毕竟感觉破坏了代码的规范性,在解决上述问题的基本前提下有没有方法解决这个小问题呢(就是让这个警告错消失的同时又不引发新的警告错)?- 已编辑 Clannad 2009年11月5日 14:12 为什么不能换行呢?
-
Hi,
-->bind.Source = Big.D1.X(i) 结果效果就会变成 OneTime 绑定,该怎么做呢?谢谢答疑
你可以自己手动设置binding的mode,像下面这样,
bind.Mode = BindingMode.TwoWay;
-->另外就是个不成问题的小问题,采用这种方法需要设置数组属性 Property X As Int32(),而这样设置会引起警告错CA1819“属性不应返回数组”。
不好意思,因为我习惯用的是C#,我把上面你的类转成C#, 并把那个属性X返回一个int[],不会出现警告错误,我想VB中属性也是可以包括数组类型的,你可以再确认一下.
-->为什么不能换行呢?
楼主你是说哪里不能换行呢?
谢谢.
Jim Zhou -MSFT -
您好:
按我上面的写法,我就是显式设置了 Mode = BindMode.TwoWay 以后,它达到的效果仍然是 OneTime 绑定,所以我才很疑惑(Tx(i) 显示的确实是创建绑定时的 X(i) 值,说明绑定成功了,然而修改 Tx(i) 不影响 X(i),修改 X(i) 也不影响 Tx(i))。这可能是什么问题呢?
您给出的 bind.Source = new List { new Big().D1.X[i] };这句代码是否表示下面的内容,是一句采用了集合初始化器的语句?
List l = new List();
l.Add(Big.D1.X[i]);
如果是这个意思,不知道 VB.NET 中有没有相应的一行代码完成创建集合和添加元素的功能,没有的话我只好老老实实写成两句了
CA1819警告错(属性不应返回数组)不是直接显示的,是“运行代码分析”后才会显示的,所以我说是个不成问题的小问题~
谢谢答疑!
我说的不能换行,是指上次回帖后,我本来换好行的内容全部被连成一行了,编辑后才正常- 已编辑 Clannad 2009年11月6日 9:24 还是那个问题
-
您好:
我终于理解了 bind.Source = new List { new Big().D1.X[i] };的含义。但由此我推测这一句是创建了新的 Big 对象,因此并不能与 bigobj 的内容进行绑定;即使改成 bind.Source = new List { bigobj.D1.X[i] };也是绑定到 X[i] 的副本,而并没有绑定到 X[i] 本身,不知道我的推测对吗?
经过测试您给的第一种方法:
bind.Source = bigobj.D1.X[i]; bind.Path = "."; //此种情况下下面的绑定模式设置无效,得到的是 OneTime 绑定 bind.Mode = BindingMode.TwoWay; Tx[i].SetBinding....
后来又发现了第二种方法:
bind.Source = bigobj.D1 bind.Path = "X[" & i.ToString & "]"; //此种情况下绑定模式有效 bind.Mode = BindingMode.TwoWay; Tx[i].SetBinding....
虽然绑定成功了,但又发现新的问题:
在代码中对 X[i] 的修改并不会引发 public int[] X 的 set 过程,从而 OnPropertyChanged("X");无法被触发,只能手动引发,明显破坏了UI与数据的解耦;
在实际应用中我的应用必须在 X 的元素 X[i] 改变时添加与 i 有关的处理代码,所以必须应用 public int X(int i) 而不是 public int[] X,而这第二种方法仍然不能应用于 public int X(int i) 的情况。
期望我的新问题能得到您的关注,谢谢!- 已编辑 Clannad 2009年11月9日 8:28 换行的问题