WPF中如何使用C#创建DataTemplate数据模版

简介:

 看到博客园有篇文章谈到“使用C#编程的方式创建DataTemplate数据模板”(原文地址), 博主的做法是创建一个FrameworkElementFactory对象,设置好后将其设置为DataTemplate对象的VisualTree属 性。我认为此方法有待商榷,盖因查阅MSDN,发现FrameworkElementFactory类的介绍页面上有一段备注:
(http://msdn.microsoft.com/zh-cn/library/system.windows.frameworkelementfactory.aspx)

  备注:通过此类以编程方式创建模板这种方式已被否决,这些模板是 FrameworkTemplate(如 ControlTemplate 或 DataTemplate)的子类;使用此类创建模板时,并非所有模板功能都可用。以编程方式创建模板的推荐方式是:使用 XamlReader 类的 Load 方法从字符串或内存流中加载 XAML。


  因此,正确的做法似乎是编程创建一段XAML代码并且使用XamlReader类的Load方法将其构造成为实例对象。下面代码展示了这一做法(为了演示,数据绑定操作全部由C#代码而不是xaml完成):

 

  下面代码完成一个小程序,该程序可以输入名字和昵称,将之加入到ListBox列表中,如果选中ListBox某一项,输入框内容会实时更新,也可以实时修改名字和昵称。首先使用XAML描述出程序界面:

MainWindow.xaml:

 

   
   
  1.  
  2.     <label>姓名</label> 
  3.  
  4.     <label>昵称</label> 
  5.  
  6. <button>增加</button> 

  下面将TextBox、ListBox的数据源全部绑定到我们自己的数据结构上,先定义一个NickName类,实现INotifyPropertyChanged接口:

MainWindow.xaml.cs:

 

   
   
  1. public class NickName: INotifyPropertyChanged  
  2. {  
  3.     public NickName() : this( “Name”, “Nick” ) { }  
  4.     public NickName( string name, string nick )  
  5.     {  
  6.         namename_ = name; nicknick_ = nick;  
  7.     }  
  8.  
  9.     public event PropertyChangedEventHandler PropertyChanged;  
  10.     private void FireEvent( string propertyName )  
  11.     {  
  12.         if( PropertyChanged != null )  
  13.         PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );  
  14.     }  
  15.  
  16.     private string name_;  
  17.     public string Name  
  18.     {  
  19.         get { return name_; }  
  20.         set{  
  21.             if( name_ == value ) return;  
  22.             name_ = value;  
  23.             FireEvent( “Name” );  
  24.         }  
  25.     }  
  26.  
  27.     private string nick_;  
  28.     public string Nick  
  29.     {  
  30.         get { return nick_; }  
  31.         set{  
  32.             if( nick_ == value ) return;  
  33.             nick_ = value;  
  34.             FireEvent( “Nick” );  
  35.         }  
  36.     }  

  下面代码在内存中使用XAML定义了一个DataTemplate,并将之实例化,完成了ListBox的数据绑定操作:

MainWindow.xaml.cs:

 

   
   
  1. public partial class MainWindow: Window  
  2. {  
  3.     //ObservableCollection<>集合实现了INotifyCollectionChanged接口  
  4.     public ObservableCollection nickNames_ = new ObservableCollection();  
  5.  
  6.     public MainWindow()  
  7.     {  
  8.         InitializeComponent();  
  9.         DoDataBinding();  
  10.         //点击“增加”按钮时将TextBox中的内容增加到nickNames_容器中  
  11.         //由于ListBox已经绑定到nickNames_,这将导致ListBox显示内容的更新  
  12.         btnAdd_.Click += ( o, e ) => {  
  13.             nickNames_.Add( new NickName() );  
  14.         };  
  15.     }  
  16.  
  17.     private void DoDataBinding()  
  18.     {  
  19.         //设定总体的数据上下文,它将影响DockPanel里面所有控件  
  20.         dockPanel_.DataContext = nickNames_;  
  21.  
  22.         //将ListBox绑定到nickNames_,并设定同步更新当前Item属性  
  23.         lstBox_.SetBinding( ListBox.ItemsSourceProperty, string.Empty );  
  24.         lstBox_.IsSynchronizedWithCurrentItem = true;  
  25.  
  26.         //内存中动态生成一个XAML,描述了一个DataTemplate  
  27.         XNamespace ns = “http://schemas.microsoft.com/winfx/2006/xaml/presentation”;  
  28.         XElement xDataTemplate =  
  29.             new XElement( ns + “DataTemplate”, new XAttribute( “xmlns”, “http://schemas.microsoft.com/winfx/2006/xaml/presentation” ),  
  30.                 new XElement( ns + “TextBlock”,  
  31.                     new XElement( ns + “TextBlock”, new XAttribute( “Width”, “100″ ), new XAttribute( “Text”, “{Binding Path=Name}” ) ),  
  32.                     new XElement( ns + “TextBlock”, new XAttribute( “Width”, “100″ ), new XAttribute( “Text”, “{Binding Path=Nick}” ) )  
  33.                 )  
  34.             );  
  35.         //将内存中的XAML实例化成为DataTemplate对象,并赋值给  
  36.         //ListBox的ItemTemplate属性,完成数据绑定  
  37.         XmlReader xr = xDataTemplate.CreateReader();  
  38.         DataTemplate dataTemplate = XamlReader.Load( xr ) as DataTemplate;  
  39.         lstBox_.ItemTemplate = dataTemplate;  
  40.         //将两个TextBox分别绑定到当前Item的Name和Nick属性上  
  41.         txtBoxName_.SetBinding( TextBox.TextProperty, “Name” );  
  42.         txtBoxNick_.SetBinding( TextBox.TextProperty, “Nick” );  
  43.     }  
  44.  

  通过上述代码,已经成功使用C#代码创建了DataTemplate数据模板,并完成了这个小程序:

 

  由于刚开始学习WPF,代码中难免有不当之处,恳请牛人指正。

By liuxiaobo

 














本文转自百度技术51CTO博客,原文链接:http://blog.51cto.com/baidutech/743790 ,如需转载请自行联系原作者
相关文章
|
22天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
34 11
|
24天前
|
开发框架 .NET Java
C#集合数据去重的5种方式及其性能对比测试分析
C#集合数据去重的5种方式及其性能对比测试分析
49 10
|
3月前
|
SQL 缓存 分布式计算
C#如何处理上亿级数据的查询效率
C#如何处理上亿级数据的查询效率
64 1
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
本文介绍了在C# WPF应用程序中引入外部iconfont图标时可能遇到的显示问题及其解决方法:1) 检查资源路径和引入格式是否正确,确保字体文件引用格式为“#xxxx”,并正确指向字体文件位置;2) 确保图标资源被包含在程序集中,通过设置字体文件的生成操作为Resource(资源)来实现。
C# WPF 中 外部图标引入iconfont,无法正常显示问题 【小白记录】
|
4月前
|
编解码 C# 数据库
C# + WPF 音频播放器 界面优雅,体验良好
【9月更文挑战第18天】这是一个用 C# 和 WPF 实现的音频播放器示例,界面简洁美观,功能丰富。设计包括播放/暂停按钮、进度条、音量控制滑块、歌曲列表和专辑封面显示。功能实现涵盖音频播放、进度条控制、音量调节及歌曲列表管理。通过响应式设计、动画效果、快捷键支持和错误处理,提升用户体验。可根据需求扩展更多功能。
169 3
|
4月前
|
存储 C# 开发者
枚举与结构体的应用:C#中的数据组织艺术
在C#编程中,枚举(`enum`)和结构体(`struct`)是非常重要的数据类型。枚举用于定义命名常量集合,提高代码可读性;结构体则封装相关数据字段,适合小型数据集。本文从基本概念入手,探讨它们的使用技巧、常见问题及解决方案,帮助开发者更好地利用这些特性构建健壮的应用程序。
63 8
|
3月前
|
中间件 数据库连接 API
C#数据分表核心代码
C#数据分表核心代码
54 0
|
3月前
|
XML JSON 前端开发
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
C#使用HttpClient四种请求数据格式:json、表单数据、文件上传、xml格式
803 0
|
5月前
|
传感器 C# 监控
硬件交互新体验:WPF与传感器的完美结合——从初始化串行端口到读取温度数据,一步步教你打造实时监控的智能应用
【8月更文挑战第31天】本文通过详细教程,指导Windows Presentation Foundation (WPF) 开发者如何读取并处理温度传感器数据,增强应用程序的功能性和用户体验。首先,通过`.NET Framework`的`Serial Port`类实现与传感器的串行通信;接着,创建WPF界面显示实时数据;最后,提供示例代码说明如何初始化串行端口及读取数据。无论哪种传感器,只要支持串行通信,均可采用类似方法集成到WPF应用中。适合希望掌握硬件交互技术的WPF开发者参考。
96 0
|
5月前
|
C# 开发者 数据处理
WPF开发者必备秘籍:深度解析数据网格最佳实践,轻松玩转数据展示与编辑大揭秘!
【8月更文挑战第31天】数据网格控件是WPF应用程序中展示和编辑数据的关键组件,提供排序、筛选等功能,显著提升用户体验。本文探讨WPF中数据网格的最佳实践,通过DevExpress DataGrid示例介绍其集成方法,包括添加引用、定义数据模型及XAML配置。通过遵循数据绑定、性能优化、自定义列等最佳实践,可大幅提升数据处理效率和用户体验。
84 0