Silverlight 通过索引器绑定动态数据
绑定动态数据是做 Silverlight 程序时经常会遇到的问题。本文介绍 Silverlight 通过绑定索引器实现绑定动态数据,即在设计时不知道数据的结构,如在设计时不知道要绑定的类有哪些属性。
绑定索引器是 Silverlight 4 新增的特性,这一特性使用我们可以在设计时不必知道要绑定的类有哪些属性,但是还可以绑定。下面先看一下如何绑定索引器。
<TextBox Grid.Row="0" Height="23" Width="148"
HorizontalAlignment="Center" VerticalAlignment="Center"
Name="txtName" Text="{Binding Path=[name]}" />
<TextBox Grid.Row="1" Height="23" Width="148"
HorizontalAlignment="Center" VerticalAlignment="Center"
Name="txtAge" Text="{Binding Path=[age]}" />
绑定索引器的语法和通常绑定数据的语法非常相似,格式为:Binding="{Binding Path=[Key]}" 。下面新建一个要绑定的 Person 类,并添加一个索引器,完整的代码如下:
public class Person : INotifyPropertyChanged
{
private Dictionary<string, object> data = new Dictionary<string, object>();
public object this[string key]
{
get
{
if (!data.ContainsKey(key))
data[key] = null;
return data[key];
}
set
{
data[key] = value;
NotifyPropertyChanged("");
}
}
public string[] Keys
{
get
{
return data.Keys.ToArray();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
下面新建一个 Person 类的实例,并绑定到第一段代码创建的两个TextBox上面。
Person person = new Person(); person["name"] = "avatar"; person["age"] = 123456; LayoutRoot.DataContext = person;
运行结果如下:
上面的代码将索引器的参数名直接写在代码中了,如果在设计时不知道类的结构,上面的代码依然无法解决问题。我们可以通过下面的代码轻松解决这个问题:
Person person = new Person();
person["name"] = "avatar";
person["age"] = 123456;
LayoutRoot.DataContext = person;
for (int i = 0; i < person.Keys.Length; i++)
{
TextBox txt = new TextBox()
{
Width = 200,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
Binding binding = new Binding("[" + person.Keys[i] + "]")
{
Mode = BindingMode.TwoWay
};
txt.SetBinding(TextBox.TextProperty, binding);
txt.SetValue(Grid.RowProperty, i);
LayoutRoot.Children.Add(txt);
}
这段代码的运行结果和上面的代码的运行结果完全一样。
以上讲的是通过索引器将单个类绑定到 Silverlight 控制上,如果要将包含多个类的列表绑定到 DataGrid 上呢?这个问题我们可以通过类似的方式轻松解决。下面是将多个类的列表绑定到 DataGrid 上的代码:
private List<Person> lst = new List<Person>();
Person person1 = new Person();
person1["name"] = "Avatar";
person1["age"] = 52342;
Person person2 = new Person();
person2["name"] = "Harry Potter";
person2["age"] = 33432;
lst.Add(person1);
lst.Add(person2);
string[] headers = person1.Keys;
for (int i = 0; i < headers.Length; i++)
{
dataGrid1.Columns.Add(new DataGridTextColumn()
{
Header = headers[i],
CanUserSort = true,
IsReadOnly = false,
Binding = new Binding("[" + headers[i] + "]")
{
Mode = BindingMode.TwoWay
}
});
}
dataGrid1.ItemsSource = lst;
注意:如果想让用户可以点击表头排序,需要设置每一列的 CanUserSort = true 。运行结果如下图:
如果需要显示 Person 类的性别,只需在上面的代码中添加:person1["gender"] = "男"; person2["gender"] = "男"; 就可以实现,运行结果如下:
示例代码下载:SLBindingDynamicObject.7z
为了你的幸福,我一直在努力!



浙公网安备 33010602011771号