Silverlight 通过索引器绑定动态数据

简介: 转自http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html绑定动态数据是做 Silverlight 程序时经常会遇到的问题。

转自http://www.cnblogs.com/forgetu/archive/2011/06/18/silverlight-binding-dynamic-object-anonymous-class.html

绑定动态数据是做 Silverlight 程序时经常会遇到的问题。本文介绍 Silverlight 通过绑定索引器实现绑定动态数据,即在设计时不知道数据的结构,如在设计时不知道要绑定的类有哪些属性。

绑定索引器是 Silverlight 4 新增的特性,这一特性使用我们可以在设计时不必知道要绑定的类有哪些属性,但是还可以绑定。下面先看一下如何绑定索引器。

1 <TextBox Grid.Row="0" Height="23" Width="148"
2             HorizontalAlignment="Center" VerticalAlignment="Center"
3             Name="txtName" Text="<span style="color: #ff0000;" color="#ff0000">{Binding Path=[name]}</span>" />
4 <TextBox Grid.Row="1" Height="23" Width="148"
5             HorizontalAlignment="Center" VerticalAlignment="Center"
6             Name="txtAge" Text="<span style="color: #ff0000;" color="#ff0000">{Binding Path=[age]}</span>" />

绑定索引器的语法和通常绑定数据的语法非常相似,格式为:Binding="{Binding Path=[Key]}" 。下面新建一个要绑定的 Person 类,并添加一个索引器,完整的代码如下:

01 public class Person : INotifyPropertyChanged
02 {
03     private Dictionary<string, object> data = new Dictionary<string, object>();
04  
05     public object this[string key]
06     {
07         get
08         {
09             if (!data.ContainsKey(key))
10                 data[key] = null;
11  
12             return data[key];
13         }
14         set
15         {
16             data[key] = value;
17             NotifyPropertyChanged("");
18         }
19     }
20  
21     public string[] Keys
22     {
23         get
24         {
25             return data.Keys.ToArray();
26         }
27     }
28  
29     public event PropertyChangedEventHandler PropertyChanged;
30  
31     public void NotifyPropertyChanged(string propertyName)
32     {
33         if (PropertyChanged != null)
34             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
35     }
36 }

下面新建一个 Person 类的实例,并绑定到第一段代码创建的两个TextBox上面。

1 Person person = new Person();
2 person["name"] = "avatar";
3 person["age"] = 123456;
4  
5 LayoutRoot.DataContext = person;

运行结果如下:

未命名

上面的代码将索引器的参数名直接写在代码中了,如果在设计时不知道类的结构,上面的代码依然无法解决问题。我们可以通过下面的代码轻松解决这个问题:

01 Person person = new Person();
02 person["name"] = "avatar";
03 person["age"] = 123456;
04  
05 LayoutRoot.DataContext = person;
06  
07 for (int i = 0; i < person.Keys.Length; i++)
08 {
09     TextBox txt = new TextBox()
10     {
11         Width = 200,
12         HorizontalAlignment = HorizontalAlignment.Center,
13         VerticalAlignment = VerticalAlignment.Center
14     };
15     Binding binding = new Binding("[" + person.Keys[i] + "]")
16     {
17         Mode = BindingMode.TwoWay
18     };
19     txt.SetBinding(TextBox.TextProperty, binding);
20  
21     txt.SetValue(Grid.RowProperty, i);
22     LayoutRoot.Children.Add(txt);
23 }

这段代码的运行结果和上面的代码的运行结果完全一样。

以上讲的是通过索引器将单个类绑定到 Silverlight 控制上,如果要将包含多个类的列表绑定到 DataGrid 上呢?这个问题我们可以通过类似的方式轻松解决。下面是将多个类的列表绑定到 DataGrid 上的代码:

1 private List<Person> lst = new List<Person>();
01 Person person1 = new Person();
02 person1["name"] = "Avatar";
03 person1["age"] = 52342;
04  
05 Person person2 = new Person();
06 person2["name"] = "Harry Potter";
07 person2["age"] = 33432;
08  
09 lst.Add(person1);
10 lst.Add(person2);
11  
12 string[] headers = person1.Keys;
13 for (int i = 0; i < headers.Length; i++)
14 {
15     dataGrid1.Columns.Add(new DataGridTextColumn()
16     {
17         Header = headers[i],
18         CanUserSort = true,
19         IsReadOnly = false,
20         Binding = new Binding("[" + headers[i] + "]")
21         {
22             Mode = BindingMode.TwoWay
23         }
24     });
25 }
26  
27 dataGrid1.ItemsSource = lst;

注意:如果想让用户可以点击表头排序,需要设置每一列的 CanUserSort = true 。运行结果如下图:

未命名

如果需要显示 Person 类的性别,只需在上面的代码中添加:person1["gender"] = "男"; person2["gender"] = "男"; 就可以实现,运行结果如下:

未命名

示例代码下载:SLBindingDynamicObject.7z

 
目录
相关文章

热门文章

最新文章