WPF中如何使用后台代码动态创建数据模板(DataTemplate)

数据模板回顾 

在WPF中数据模板可以控制数据的呈现方式。

对于一些简单的数据,例如一个string,一个int,在显示时,无须额外控制 。

但是对于复杂数据类型,就需要使用数据模板来控制数据的呈现方式。

一个简单的例子

假设 我们定义了一个学生类

1     public class Student
2     {
3         public int Id { get; set; }
4 
5         public string Name { get; set; }
6     }

然后定义了一个学生列表,并绑定到ListBox

1   var list = new List<Student>();
2   list.Add(new Student() {Id = 1,Name = "意在" });
3   list.Add(new Student() { Id = 2, Name = "奎文" });
4 
5   this.list1.ItemsSource = list;

在未使用数据模板前,显示的效果如下:

1  <ListBox Name="list1"></ListBox>

使用了数据模板,显示效果如下:

 1     <ListBox Name="list2" Grid.Row="1">
 2         <ListBox.ItemTemplate>
 3             <DataTemplate>
 4                 <WrapPanel>
 5                     <Label Content="{Binding Id}" FontWeight="Bold" FontSize="20"></Label>
 6                     <Label Content="{Binding Name}" FontFamily="Arial"></Label>
 7                 </WrapPanel>
 8             </DataTemplate>
 9         </ListBox.ItemTemplate>
10     </ListBox>

如何动态创建数据模板

官方的建议是使用 XamlReader.Load 方法从字符串或内存流加载 XAML而不是以编程的方式实现。

这里这两种方式都介绍一下

1、使用XamlReader.Load方法

创建本地XAML文件

1 <DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition Height="30" /></Grid.RowDefinitions><Image Source="{Binding ImageUrl}" Width="150" Height="150" /><Label Content="{Binding Title}" FontWeight="Bold" HorizontalAlignment="Center" Grid.Row="1" /></Grid></DataTemplate>

加载XAML文件转换为数据模板并设置到控件上

1 var templateFile = Environment.CurrentDirectory + "\\template.xaml";
2 var xaml = System.IO.File.ReadAllText(templateFile);
3 using(StringReader sr = new StringReader(xaml))
4 {
5     XmlReader reader = XmlReader.Create(sr);
6     var template = XamlReader.Load(reader) as DataTemplate;
7     this.listbox.ItemTemplate = template;
8 }

2、使用代码创建数据模板

DataTamplate类可以被实例化,在创建一个DataTamplate对象后,我们需要设置它的VisualTree字段值

VisualTree字段需要的是一个FrameworkElementFactory类型,它可以支持模板创建。

可以看到这个类型的后缀是Factory,所以这里采用了工厂模式,工厂模式是一种常见的设计模式 ,它指的是根据给定的参数动态创建类型,以达到解耦的目的。

还是以上面同样的数据模板进行演示

首先我们创建一个DataTemplate对象

1  DataTemplate template = new DataTemplate();

创建一个Grid

1 FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid));

为Grid添加行定义

1 //创建行
2 FrameworkElementFactory row1 = new FrameworkElementFactory(typeof(RowDefinition));
3 FrameworkElementFactory row2 = new FrameworkElementFactory(typeof(RowDefinition));
4 row2.SetValue(RowDefinition.HeightProperty, new GridLength(30));
5 
6 //添加行
7 gridFactory.AppendChild(row1);
8 gridFactory.AppendChild(row2);

添加Image控件

1  //添加图像
2  FrameworkElementFactory imageFactory = new FrameworkElementFactory(typeof(Image));
3  imageFactory.SetValue(Image.SourceProperty, new Binding("ImageUrl"));  //Source
4  imageFactory.SetValue(Image.WidthProperty, 150d);                      //Width
5  imageFactory.SetValue(Image.HeightProperty, 150d);                     //Height
6  gridFactory.AppendChild(imageFactory);

添加Label控件

1   //添加标题
2   FrameworkElementFactory labelFactory = new FrameworkElementFactory(typeof(Label));
3   labelFactory.SetValue(Label.ContentProperty, new Binding("Title")); //内容
4   labelFactory.SetValue(Label.FontWeightProperty, FontWeights.Bold);  //加粗
5   labelFactory.SetValue(Grid.RowProperty, 1);                         //Grid.Row = 1
6   labelFactory.SetValue(Label.HorizontalAlignmentProperty, HorizontalAlignment.Center);//HorizontalAlignment
7   gridFactory.AppendChild(labelFactory);

最后将grid设置到DataTemplateVisualTree上,我们就得到一个动态的数据模板(DataTemplate)对象

1  template.VisualTree = gridFactory;

运行效果

示例代码

github

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF ,可以使用后台代码绑定数据,以下是一些常用的绑定方式: 1. 绑定到属性:可以使用 Binding 对象将控件的属性与后台数据源的属性绑定起来。例如: ``` // 假设 DataContext 是一个对象,其有一个名为 Name 的属性 Binding binding = new Binding("Name"); binding.Source = DataContext; textBox.SetBinding(TextBox.TextProperty, binding); ``` 上面的代码将一个 TextBox 的 Text 属性与 DataContext 对象的 Name 属性绑定起来,当 DataContext 对象的 Name 属性发生变化时,TextBox 的文本也会随之更新。 2. 绑定到集合:可以使用 Binding 对象将控件的 ItemsSource 属性与后台数据源的集合绑定起来。例如: ``` // 假设 DataContext 是一个集合,例如 List<string> Binding binding = new Binding(); binding.Source = DataContext; listBox.SetBinding(ListBox.ItemsSourceProperty, binding); ``` 上面的代码将一个 ListBox 的 ItemsSource 属性与 DataContext 对象绑定起来,当 DataContext 对象的集合发生变化时,ListBox 的列表也会随之更新。 3. 绑定到命令:可以使用 CommandBinding 对象将控件的命令与后台的 ICommand 对象绑定起来。例如: ``` // 假设 DataContext 是一个实现了 ICommand 接口的对象 CommandBinding binding = new CommandBinding(ApplicationCommands.Open); binding.Executed += (sender, e) => DataContext.Execute(null); this.CommandBindings.Add(binding); ``` 上面的代码将一个按钮的 Command 属性与 DataContext 对象绑定起来,当按钮被点击时,DataContext 对象的 Execute 方法会被调用。 以上是一些常用的 WPF 后台代码绑定数据的方式,您可以根据具体的需求选择适合的绑定方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值