WPF中ControlTemplate和wpf获取datatemplatee的区别

wpf 模板选择器DataTemplateSelector及动态绑定使用教程 | 熊窝窝
其实也说不上算是教程了,只是把自己学习的代码拿出来分享一下,同时方便以后遇到类似问题的时候翻一下。
MSDN里如是说:
通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelector。请注意,如果具有不同类型的对象,则可以对 DataTemplate 设置 DataType 属性。如果您执行了此操作,则无需创建 DataTemplateSelector。此外,如果对象类型相同但属性不同,也可以考虑使用 DataTrigger 或数据转换器。
通俗讲,就是根据不同的数据选择不同的模板。接下来,我用一个例子来讲述DataTemplateSelector和动态绑定的使用方法。
先看例子的UI:
一个Listbox三个button,listbox显示一个集合的数据,第一个button “change”点击后可以切换与listbox绑定的集合,第二个button给PersonCollection添加person实例,第三个button给AnimalCollection添加animal实例。
默认情况下listbox与PersonCollection绑定,程序启动后,点击Add person按钮会向PersonCollection添加一个person实例,listbox会显示该集合下数据,如果person类的gender属性为Female,则只显示name属性,并把边框改成蓝色。点击change后,listbox与AnimalCollection绑定,显示AnimalCollection数据,同样,Add animal添加animal实例,如果第二个属性不是4,则只显示animal的type属性,并修改边框为蓝色。
下面讲实现
第一步:建两个类,一个person,一个animal,这就是每个listbox item将来要显示的数据。
1234567891011121314151617181920212223242526272829303132333435363738394041424344//person类
& & public class person : INotifyPropertyChanged
& & {
& & & & public event PropertyChangedEventHandler PropertyChanged;
& & & & private string _name;
& & & & public string name
& & & & {
& & & & & & get
& & & & & & {
& & & & & & & & return _name;
& & & & & & }
& & & & & & set
& & & & & & {
& & & & & & & & if (value != _name)
& & & & & & & & {
& & & & & & & & & & _name = value;
& & & & & & & & & & prochanged(&name&);
& & & & & & & & }
& & & & & & }
& & & & }
& & & & private string _gender;
& & & & public string gender
& & & & {
& & & & & & get
& & & & & & {
& & & & & & & & return _gender;
& & & & & & }
& & & & & & set
& & & & & & {
& & & & & & & & if (value != _gender)
& & & & & & & & {
& & & & & & & & & & _gender = value;
& & & & & & & & & & prochanged(&gender&);
& & & & & & & & }
& & & & & & }
& & & & }
& & & & private void prochanged(string info)
& & & & {
& & & & & & if (PropertyChanged != null)
& & & & & & {
& & & & & & & & PropertyChanged(this,
PropertyChangedEventArgs(info));
& & & & & & }
& & & & }
& & }
注意到这里,实现了INotifyPropertyChanged接口,需要引用命名空间ponentModel.因为我希望这些属性改变的时候,listboxitem能自动更新,关于INotifyPropertyChanged接口,请看我另一篇日志。
另一个类,animal与person基本类似,只是把person类里的属性:name和gender改成了type和legs。这里我就不贴代码了。
第二步:创建类DataContainer,包含两个集合,存储animal和person实例。代码:
12345678910& & public class DataContainer
& & {
& & & & public &ObservableCollection&person& PersonCollection { get;set; }
& & & & public &ObservableCollection&animal& AnimalCollection { get; set; }
& & & & public DataContainer()
& & & & {
& & & & & & PersonCollection =
ObservableCollection&person&();
& & & & & & AnimalCollection =
ObservableCollection&animal&();
& & & & }
& & }
我用了ObservableCollection,因为ObservableCollection已经实现了INotifyPropertyChanged接口,所以如果集合的项增删的时候UI会自动更新。(using System.Collections.ObjectM//ObservableCollection)
注意:假设最上面第一段代码person类里面,没有实现INotifyPropertyChanged接口,而这里仍然使用ObservableCollection来存储person列表的话,PersonCollection 里的项增加或删除时,UI的listbox也会相应的增删,但是当你想修改PersonCollection里某一个person实例的属性,比如gender由male变成female时,UI并不会更新,因为PersonCollection 并没变。所以,当你希望改变UI listbox item里某个person的属性时,person类就需要实现INotifyPropertyChanged接口。
第三步:定义数据模板。
当然首先在窗口里把需要的listbox和button放好。我的XAML代码如下:
1234567& & &Grid&
& & & & &ListBox Margin=&12,12,12,60& Name=&listBox1& & HorizontalContentAlignment =&Stretch& ItemTemplateSelector=&{StaticResource mytemplate_selector}&&
& & & & &/ListBox&
& & & & &Button Height=&23& HorizontalAlignment=&Left& Margin=&12,0,0,12& Name=&Change& VerticalAlignment=&Bottom& Width=&75& Click=&Change_Click&&Change&/Button&
& & & & &Button Height=&23& Margin=&120,0,109,12& Name=&addperson& VerticalAlignment=&Bottom& Click=&addperson_Click&&Add person&/Button&
& & & & &Button Height=&23& HorizontalAlignment=&Right& Margin=&0,0,12,12& Name=&addanimal& VerticalAlignment=&Bottom& Width=&75& Click=&addanimal_Click&&Add animal&/Button&
& & &/Grid&
吃饭去了,回来再写……
继续,上面的XAML里的3个button没什么好说的,listbox里,最重要的一句是:ItemTemplateSelector=”{StaticResource mytemplate_selector}”,从字面意思理解,就是把一个叫做mytemplate_selector的静态资源,做为listbox的模板选择器。所以,接下来,定义我们需要资源,包括一个模板选择器和四个数据模板。模板选择器就是这里的mytemplate_selector,四个模板,person和animal各两个,通过模板选择器选择使用哪一个。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253& & &Window.Resources&
& & & & &local:MyDataTemplateSelector x:Key=&mytemplate_selector& /&
& & & & &DataTemplate x:Key =&person_template&&
& & & & & & &Border &Name=&myborder& BorderBrush=&Blue& Padding=&5& Margin=&2& BorderThickness=&1&&
& & & & & & &StackPanel&
& & & & & & & & &TextBlock &Text=&{Binding Path=name}&&&/TextBlock &
& & & & & & & & &TextBlock &Text=&{Binding Path=gender}&&&/TextBlock &
& & & & & & &/StackPanel&
& & & & & & &&/Border&
& & & & & & &DataTemplate.Triggers&
& & & & & & & & &DataTrigger &Value=&Male& Binding=&{Binding Path=gender}&& & & & & &
& & & & & & & & & & &Setter TargetName=&myborder& Property=&BorderBrush& Value=&Red& /&
& & & & & & & & &/DataTrigger&
& & & & & & &/DataTemplate.Triggers&
& & & & &/DataTemplate&
& & & & &DataTemplate x:Key=&male_template&&
& & & & & & &DataTemplate.Resources&
& & & & & & & & &Style TargetType=&TextBlock&&
& & & & & & & & & & &Setter Property=&FontSize& Value=&20& /&
& & & & & & & & &/Style&
& & & & & & &/DataTemplate.Resources&
& & & & & & &Border &Name=&myborder_male& BorderBrush=&Blue& Padding=&5& Margin=&2& BorderThickness=&1&&
& & & & & & & & &DockPanel&
& & & & & & & & & & &TextBlock Text=&{Binding Path=name}&/&
& & & & & & & & &/DockPanel&
& & & & & & &/Border&
& & & & &/DataTemplate&
& & & & &DataTemplate x:Key =&animal_template&&
& & & & & & &Border &Name=&myborder& BorderBrush=&Blue& Padding=&5& Margin=&2& BorderThickness=&1&&
& & & & & & & & &StackPanel&
& & & & & & & & & & &TextBlock &Text=&{Binding Path=type}&&&/TextBlock &
& & & & & & & & & & &TextBlock &Text=&{Binding Path=legs}&&&/TextBlock &
& & & & & & & & &/StackPanel&
& & & & & & &/Border&
& & & & & & &DataTemplate.Triggers&
& & & & & & & & &DataTrigger &Value=&4& Binding=&{Binding Path=legs}&&
& & & & & & & & & & &Setter TargetName=&myborder& Property=&BorderBrush& Value=&Red& /&
& & & & & & & & &/DataTrigger&
& & & & & & &/DataTemplate.Triggers&
& & & & &/DataTemplate&
& & & & &DataTemplate x:Key=&fourlegs_template&&
& & & & & & &DataTemplate.Resources&
& & & & & & & & &Style TargetType=&TextBlock&&
& & & & & & & & & & &Setter Property=&FontSize& Value=&20& /&
& & & & & & & & &/Style&
& & & & & & &/DataTemplate.Resources&
& & & & & & &Border &Name=&myborder_male& BorderBrush=&Blue& Padding=&5& Margin=&2& BorderThickness=&1&&
& & & & & & & & &DockPanel&
& & & & & & & & & & &TextBlock Text=&{Binding Path=type}&/&
& & & & & & & & &/DockPanel&
& & & & & & &/Border&
& & & & &/DataTemplate&
& & &/Window.Resources&
分析前面的XAML,在里面,我们共定义了五个资源,我简单分析一下前三个,后面两个跟第二个、第三个差不多,就不说多了。
第一个资源,定义了一个模板选择器,使用CS文件里的MyDataTemplateSelector类来选择模板。第二个资源,person_template, StackPanel里定义了普通的模板,显示person的name和gender,DataTrigger里定义了一个触发器,当gender为Male的时候,将item的border变成红色。这就是前面UI里不同的边框色的实现关键点。第三个资源male_template,定义了一个Male专用的模板,字体20号,只显示name。person_template模板里,边框颜色的变换通过DataTrigger就能实现,因为要修改的属性是在模板里存在的。但是当你想修改一些模板里不存的属性或者对于gender = male时使用另外完全不同的模板,那就要用到模板选择器了。下面分析前面提到的模板选择器,看着比较多,其实很简单,忍一忍认真点儿看完,你就能有更多收获。
12345678910111213141516171819202122232425262728293031323334353637//必须继承自DataTemplateSelector
&public class MyDataTemplateSelector:DataTemplateSelector
& & {
& & & & //覆盖SelectTemplate函数
& & & & public override DataTemplate SelectTemplate(object item, DependencyObject container)
& & & & {
& & & & & & Window win = Application.Current.MainWindow;
& & & & & & //当前正在显示的是person类数据时:
& & & & & & if (item != null && item
person)
& & & & & & { & & & & & & &
& & & & & & & & person p = item as person;
& & & & & & & & //如果gender是male,将person_template做为现在的模板
& & & & & & & & if (p.gender==&Male&)
& & & & & & & & {
& & & & & & & & & & return win.FindResource(&person_template&) as DataTemplate;
& & & & & & & & }
& & & & & & & & //否则就使用male_template
& & & & & & & & else
& & & & & & & & {
& & & & & & & & & & return win.FindResource(&male_template&) as DataTemplate;
& & & & & & & & }
& & & & & & }
& & & & & & else if(item != null && item
animal)
& & & & & & {
& & & & & & & & animal a = item as animal;
& & & & & & & & if (a.legs==4)
& & & & & & & & {
& & & & & & & & & & return win.FindResource(&animal_template&) as DataTemplate;
& & & & & & & & }
& & & & & & & & else
& & & & & & & & {
& & & & & & & & & & return win.FindResource(&fourlegs_template&) as DataTemplate;
& & & & & & & & }
& & & & & & }
& & & & & & return null;
& & & & }
& & }
程序初初始化的时候:
1234567891011& & & & private bool isPersonDisplaying;
& & & & private DataContainer dc;
& & & & public Window1()
& & & & {
& & & & & & InitializeComponent();
& & & & & & //表示当前正在显示的数据。默认显示person
& & & & & & isPersonDisplaying = true;
& & & & & & dc =
DataContainer();
& & & & & & //指定数据源
& & & & & & listBox1.ItemsSource = dc.PersonCollection;
& & & & }
三个按钮的函数,change:
1234567891011121314151617private void Change_Click(object sender, RoutedEventArgs e)
& & & & {
& & & & & & changeBindingPath();
& & & & }
& & & & private void changeBindingPath()
& & & & {
& & & & & & if (isPersonDisplaying)
& & & & & & {
& & & & & & & & listBox1.ItemsSource = dc.AnimalCollection;
& & & & & & & & isPersonDisplaying = false;
& & & & & & }
& & & & & & else
& & & & & & {
& & & & & & & & listBox1.ItemsSource = dc.PersonCollection;
& & & & & & & & isPersonDisplaying = true;
& & & & & & }
& & & & }
这里实现不同数据源的切换,当数据源变换的时候,WPF会调用前面我们定义的模板选择器,选择正确的模板。
两个增加数据的函数:
12345678910111213141516&private void addperson_Click(object sender, RoutedEventArgs e)
& & & & {
& & & & & & person p =
person();
& & & & & & p.name = &PersonName& + System.DateTime.Now.Second.ToString();
& & & & & & string gender = (System.DateTime.Now.Second%2)==1?&Male&:&Female&;
& & & & & & p.gender = gender;
& & & & & & dc.PersonCollection.Add(p);
& & & & }
& & & & private void addanimal_Click(object sender, RoutedEventArgs e)
& & & & {
& & & & & & animal a =
animal();
& & & & & & a.type = &AnimalType& + System.DateTime.Now.Second.ToString();
& & & & & & a.legs = (System.DateTime.Now.Second % 2) == 1 ? 2 : 4;
& & & & & & dc.AnimalCollection.Add(a);
& & & & }
表达能力一般,水平一般,大家见谅。源代码我打了个包,,编译环境:vs2008。
本条目发布于。属于分类。作者是。
有人回复时邮件通知我
2017年一月 &(2)
2016年七月 &(1)
2016年四月 &(1)
2016年二月 &(1)
2016年一月 &(5)
2015年十一月 &(2)
2015年十月 &(84)
2015年五月 &(2)
2015年四月 &(2)
2015年二月 &(1)
2015年一月 &(2)
2014年十二月 &(4)
2014年十一月 &(3)
2014年十月 &(1)
2014年九月 &(4)
2014年八月 &(1)
2014年四月 &(4)
2014年三月 &(8)
2014年二月 &(1)
2014年一月 &(1)
2013年三月 &(2)
2013年二月 &(2)
2012年十二月 &(2)
2012年十一月 &(2)
2012年九月 &(2)
2012年八月 &(3)
2012年七月 &(3)
2012年六月 &(2)
2012年五月 &(1)
2012年四月 &(2)
2012年二月 &(1)
2012年一月 &(1)
2011年十月 &(1)
2011年八月 &(1)
2011年七月 &(2)
2011年六月 &(14)
2011年五月 &(6)
2011年四月 &(9)
2011年三月 &(2)
2011年一月 &(7)
2010年十二月 &(8)
2010年十一月 &(1)
2010年十月 &(4)
2010年九月 &(1)
2010年八月 &(2)
2010年七月 &(3)
2010年六月 &(10)
2010年五月 &(6)
2010年四月 &(15)
2010年三月 &(17)
2010年二月 &(15)
2010年一月 &(26)
2009年十二月 &(22)
2009年十一月 &(35)
2009年十月 &(18)
2009年九月 &(5)
2009年八月 &(3)
2009年七月 &(1)
2009年六月 &(1)
2009年五月 &(2)
2009年四月 &(7)博客访问: 3461987
博文数量: 1920
博客积分: 10870
博客等级: 上将
技术积分: 19795
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
ControlTemplate用于描述控件本身. 使用TemplateBinding来绑定控件自身的属性, 比如{TemplateBinding Background}DataTemplate用于描述控件的Content. 使用Binding来绑定数据对象的属性, 比如{Binding PersonName}一般来说, ControlTemplate内有一个ContentPresenter, 这个ContentPresenter的ContentTemplate就是DataTemplate类型Control类型&&& - Template属性 (ControlTemplate类型)&&&&&&& - ContentPresenter&&&&&&&&&&& - ContentTemplate (DataTemplate类型)ContentControl类型&&& - Template属性 (ControlTemplate类型) 继承自Control&&& - ContentTemplate (DataTemplate类型)ItemsControl类型&&& - Template属性 (ControlTemplate类型) 继承自Control&&& - ItemsPanel属性 (ItemsPanelTemplate类型)&指定布局容器&&& - ItemTemplate属性 (DateTemplate类型) 每个Item的Template
阅读(1791) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。WPF支持以下类型的模板:
(1) 控件模板。控件模板可以将自定义模板应用到某一特定类型的所有控件,或是控件的某一实例。决定控件外观的是ControlTemplate,它决定了控件&长成什么样子&,因此控件模板由ControlTemplate类表示。控件模板实际在资源集合或资源字典中定义。例子详见:(/zhouhb/p/3284780.html)。
(2) 数据模板。在WPF中,决定数据外观的是DataTemplate,即DataTemplate是数据内容的表现形式,一条数据显示成什么样子,是简单的文本还是直观的图形,就是由DataTemplate决定的。例子详见:(/zhouhb/p/3284827.html)。
(3)ItemsPanelTemplate模板。ItemsPanelTemplate 指定用于项的布局的面板。如下面的例子通过设置ListBox的ItemsPanelTemplate,使得每一项从左至右按顺序显示。
因为WrapPanel从左至右按顺序位置定位子元素,在包含框的边缘处将内容断开至下一行。 后续排序按照从上至下或从右至左的顺序进行,具体取决于 Orientation 属性的值(默认值为 Horizontal)。
&ListBox AllowDrop="True" Margin="0,1,262,0"&
&ListBox.ItemsPanel&
&ItemsPanelTemplate&
&WrapPanel/&
&/ItemsPanelTemplate&
&/ListBox.ItemsPanel&
&Label Name="label1" Content="E" /&
&Label Name="label2" Content="A" /&
&Label Name="label3" Content="I" /&
&Label Name="label4" Content="M" /&&/ListBox&
运行效果:
关于WPF三大模版的学习,可以进一步参照:(/dingli/archive//2112150.html)。
阅读(...) 评论()WPF中的UserControl==DataTemplate的!!!_Windows Presentation_平台,框架和库_或代码
| 文章 >> 平台,框架和库 >> Windows Presentation
WPF中的UserControl==DataTemplate的!!!
{A} {S0}简介如果你学习WPF或使用WPF广泛,你将毫无疑问的DataTemplates需要。 DataTemplates允许开发人员定义,什么是约束,并呈现在用户界面从底层的应用程序对象。他们,说白了,无处不在,当谈到在WPF用户界面显示数据。当你有一个对象,以显示在用户界面逻辑和常用的方法收集,一个DataTemplate是首选的方法来定义这些元素的外观和感觉,一旦呈现在UI。这些燃料的一致性,本质上​​是可重复使用的。本文附带的演示源代码是很简单,但如果你结合其他的可能性,如值转换器,这些想法,你会很快发现,你有一个非常强大的UI工具在您的处置。有很多很多的代码项目的信息来源和互联网在一般情况下,可以解释一般DataTemplate的校长比一,以最好的地方开始学习一些定义的基础和使用DataTemplates将MSDN文档,可以在这里找到:。内联模板 DataTemplates通常被定义为"内联",这意味着他们的主要"消耗"的XAML文件内的项目控制XAML结构构造,如:&ListBox Width=&400& Margin=&10&
ItemsSource=&{Binding Source={StaticResource myTodoList}}&&
&ListBox.ItemTemplate&
&DataTemplate&
&StackPanel&
&TextBlock Text=&{Binding Path=TaskName}& /&
&TextBlock Text=&{Binding Path=Description}&/&
&TextBlock Text=&{Binding Path=Priority}&/&
&/StackPanel&
&/DataTemplate&
&/ListBox.ItemTemplate&
&/ListBox&,他们往往包含在参考资料一节的一个窗口,网页,或控制,如:{C}替代品其他的方法之一是可能实际上并不似乎得到多少按。说实话,我个人觉得我在这里覆盖的方法
是"同意"在关系到整个设计范式,WPF在我们抛出。您可以使用DataTemplates的UserControls!这是一个整洁的解决方案,我坐下来,一起把这个小演示如何做到这一点,让其他人可以得到一个容易看的想法,并开始使用这种方法。
有一点就是不断有关WPF的能力,让"松散耦合"的应用程序逻辑和用户界面实现。 DataTemplates使用而设计的UserControls,你真的可以采取进一步的,有一个干净的分离之间的主窗口或页面XAML和DataTemplates。无论如何,让我们来看看一些代码!使用代码这个演示中,我开始通过创建一个普通的Visual Studio 2008解决方案。然后,我定义了DataItem的类来保存在UI中显示的一些数据:
public sealed class DataItem
public string Name { get; set; }
public int Age { get; set; }
public double Progress { get; set; }
public DataItem(string name, int age, double progress)
Progress =
}现在,我们有一个简单的对象定义,我们要在UI中显示,我们需要设置此对象的消费并填充一些数据。要做到这一点,我简单地定义在窗口的ObservableCollection,创造了一个方法,酿在收集到一些的DataItem对象:ObservableCollection&DataItem& items = new ObservableCollection&DataItem&();在主窗口中的代码隐藏文件,我添加了这种方法:void PopulateDataItems()
items.Add(new DataItem(&Jammer&, 32, 10.0));
items.Add(new DataItem(&John&, 44, 20.0));
items.Add(new DataItem(&Jane&, 25, 30.0));
items.Add(new DataItem(&Robert&, 30, 40.0));
items.Add(new DataItem(&Jezzer&, 50, 50.0));
items.Add(new DataItem(&James&, 40, 60.0));
items.Add(new DataItem(&Rebecca&, 25, 70.0));
items.Add(new DataItem(&Mark&, 35, 80.0));
items.Add(new DataItem(&Leah&, 20, 90.0));
items.Add(new DataItem(&WallE&, 700, 100.0));
}完成!我们现在有一个窗口的代码隐藏定义一个集合,并增加了正确的对象,领取在UI中显示。接下来要看看是XAML使用本WPF善良。首先,我创建了一个UserControl(ProgressReporter.xaml)显示进展的DataItem类属性:&UserControl
x:Class=&UserControlAsDataTemplateDemo.UserControls.ProgressReporter&
xmlns=&/winfx/2006/xaml/presentation&
xmlns:x=&/winfx/2006/xaml&
x:Name=&ProgressControl&
Height=&Auto& Width=&Auto&&
&ProgressBar x:Name=&UIReporter&
Value=&{Binding PercentToShow, ElementName=ProgressControl}&
HorizontalAlignment=&Stretch&
VerticalAlignment=&Stretch&
Style=&{DynamicResource ProgressReporterStyle}& /&
&/UserControl& 此控件的代码隐藏ProgressBar的使用,以获得其价值也定义一个自定义的DependencyProperty:
public static DependencyProperty PercentProperty =
DependencyProperty.Register(&PercentToShow&,
typeof(double), typeof(ProgressReporter));
public double PercentToShow
get { return (double)GetValue(PercentProperty); }
set { SetValue(PercentProperty, value); }
}下一步是将要使用的DataTemplate的UserControl。&UserControl
x:Class=&UserControlAsDataTemplateDemo.UserControls.ItemTemplateControl&
xmlns=&/winfx/2006/xaml/presentation&
xmlns:x=&/winfx/2006/xaml&
xmlns:UserControls=&clr-namespace:UserControlAsDataTemplateDemo.UserControls&
Height=&Auto& Width=&Auto&&
&Border BorderThickness=&2,2,2,2&
CornerRadius=&5,5,5,5&
Background=&#FF626262&
BorderBrush=&#FFFFAC00&
Grid.ColumnSpan=&2&&
&Grid.ColumnDefinitions&
&ColumnDefinition Width=&*&/&
&ColumnDefinition Width=&*&/&
&ColumnDefinition Width=&*&/&
&/Grid.ColumnDefinitions&
&TextBox HorizontalAlignment=&Stretch&
VerticalAlignment=&Stretch&
Text=&{Binding Path=Name}&
TextWrapping=&Wrap&
Margin=&4,4,4,4&
Grid.ColumnSpan=&1&/&
&TextBox HorizontalAlignment=&Stretch&
VerticalAlignment=&Stretch&
Text=&{Binding Path=Age}&
TextWrapping=&Wrap&
Grid.Column=&1&
Margin=&4,4,4,4&
Grid.ColumnSpan=&1&/&
&UserControls:ProgressReporter
HorizontalAlignment=&Stretch&
VerticalAlignment=&Stretch&
PercentToShow=&{Binding Path=Progress}&
Grid.Column=&2& Margin=&4,4,4,4& /&
&/UserControl&这里要注意的要点是绑定设置。你可以看到文本框绑定的姓名和年龄属性DataItem的类,和自定义的DependencyProperty称为PercentToShow是用来约束的双重属性从DataItem的类进展ProgressReporter控制。下面的图像显示在Expression Blend中的DataTemplate的UserControl: {S2}现在,我们已经"DataTemplate的"UserControl的定义,唯一剩下要做的就是写的XAML将在MainWindow使用此控制作为一个DataTemplate。此XAML的样子:&ListBox x:Name=&peopleListBox&
HorizontalAlignment=&Stretch&
VerticalAlignment=&Stretch&
ItemContainerStyle=&{StaticResource ListBoxItemStretch}&
Foreground=&Transparent&
BorderBrush=&Transparent&
Background=&Transparent&
Grid.ColumnSpan=&2&&
&ListBox.ItemTemplate&
&DataTemplate&
&UserControls:ItemTemplateControl Margin=&4& /&
&/DataTemplate&
&/ListBox.ItemTemplate&
&/ListBox&所以,当您运行的应用程序和命中[加载数据]按钮,它使用的PopulateDataItems()方法,然后结合的ObservableCollection"项目"到ListBox,并呈现每个DataItem的使用我们的UserControl:private void btnLoadData_Click(object sender, RoutedEventArgs e)
items.Clear();
PopulateDataItems();
peopleListBox.ItemsSource =
}添加使用代码隐藏在动态行为一旦你已经定义和一个DataTemplate使用您的自定义UserControl的,你很可能想使他们有点更聪明,更WPF'y。有多种方式,通过使用触发器,DataTriggers,和值转换器等机制。除了这个,我们现在可以做的一件事是简单的使用C#代码隐藏文件建立到DataTemplate中的一些动态行为。你会发现完整的源代码为这在本文开头包含的源文件的动态的例子。为了充分展现这个充满活力的行为,我已经作出了一些改变原始样本中使用的数据创建方法;我有随机的进展值在DataItems这样做:private void PopulateDataItems()
items.Add(new DataItem(&Jammer&, 32, MakeRandomDouble()));
items.Add(new DataItem(&John&, 44, MakeRandomDouble()));
items.Add(new DataItem(&Jane&, 25, MakeRandomDouble()));
items.Add(new DataItem(&Robert&, 30, MakeRandomDouble()));
items.Add(new DataItem(&Jezzer&, 50, MakeRandomDouble()));
items.Add(new DataItem(&James&, 40, MakeRandomDouble()));
items.Add(new DataItem(&Rebecca&, 25, MakeRandomDouble()));
items.Add(new DataItem(&Mark&, 35, MakeRandomDouble()));
items.Add(new DataItem(&Leah&, 20, MakeRandomDouble()));
items.Add(new DataItem(&WallE&, 700, MakeRandomDouble()));
private double MakeRandomDouble()
int randomnumber = _random.Next(1, 100);
return (double)
}驱动的动态行为,将作出反应,这种随机的数据,我在代码中添加ItemTemplateControl的Loaded事件:Loaded=&UserControl_Loaded&加载的事件被触发后的数据绑定发生后运行元素的布局已。这意味着我们已经获得的实际数据值,以便作出相应的反应这些价值观和我们想要的变化太之前在UI中显示。在此事件处理程序的代码如下:private void UserControl_Loaded(object sender, RoutedEventArgs e)
if (Convert.ToInt32(this.AgeTextBox.Text) & 40)
SolidColorBrush brush = new SolidColorBrush();
brush.Color = Colors.DarkG
MainBorder.Background =
if (this.ProgressReporter.PercentToShow & 80.0)
SolidColorBrush brush = new SolidColorBrush();
brush.Color = Colors.L
MainBorder.Background =
Animations.Fade(this, 0.0, (ProgressReporter.PercentToShow / 100), 1000);
}这是所有相当简单的东西。使这里的一个主要的一点是,我们有一些控件的名称,使用X:名称="";这使我们能够方便地访问这些控件关联的类。我们反应的数字价值AgeTextBox.Text的ProgressReporter PercentToShow价值。在每一种情况下,我们再创建一个新的SolidColorBrush对象和申请MainBorder对象的背景颜色,以突出控制基于绑定值的UI。您还会注意到,我们使用的是一个扩展方法,包装一个所谓的淡入淡出()的DoubleAnimation。为了添加一些更多WPFness的,我已经创建了一个新的静态类被称为动画,看起来像这样:public static class Animations
static Animations()
public static void Fade(this UIElement control,
double sourceOpacity, double targetOpactity, int milliseconds)
control.BeginAnimation(UIElement.OpacityProperty,
new DoubleAnimation(sourceOpacity,targetOpactity,
new Duration(TimeSpan.FromMilliseconds(milliseconds))));
}和我们走,我们现在已经在一些很酷的动态行为添加代码背后的一个UserControl使用。这可能是大规模扩大,但较复杂的例子。 {S3}这是一次总结(每)从我的角度来看,这种方法的主要好处之一是,在设计DataTemplates时,很容易感到断开从实际的设计过程。通过使用一个DataTemplate的UserControl,你所提供的使用Expression Blend的完整的设计流程写XAML的DataTemplate。就个人而言,我觉得这是一个令人信服的理由使用这种方法最D​​ataTemplate的设计,除非你使用的是一个很基本的的设计结合的DataTemplate内,您可能需要的任何元素的预定义样式。无论哪种方式,我希望这个小演示已经很有用,你发现这种方法的一些使用。这仅仅是走过场的潜力!历史日 - 最初版本。08 2008年8月 - 加入动态代码示例。
关于作者:
中国我是一名编程爱好者,谢谢为我们提供一个学习和分享的平台。有什么问题。可以就本内容回复,我看到时。会尽量回复的。
评论会员:
时间: Xanblax评论会员:
时间:非常有用。为了得到一个用户控件Li​​stView的是必须在许多UI案件。而且它也不是那么明显,因为它应该是在VS。这篇文章解释了它整洁干净。mbthe2nd评论会员:
时间:喜干扰机。大文章。我只需要一件事之前,我可以遵循此办法。这种方法改变所有boundable控制(标签和textBlocks)的文本为空在WPF设计器(苹果酒)。这意味着我的UserControl的是仍然没有可读的一个设计师的工作就可以了,因为没有在标签上的文字。当然,这是更好地将其转换为一个DataTemplate未能看到任何。我搜索了一点点,但主要是我发现如果图像无法找到能够添加替代文本,图像占位符。,我所需要的东西真的与此类似,但与绑定文本。我居然发现,发布此消息之前,完整性,我想过它写在这里。你只需要简单地写这个子节点:LT;TextBlock.TLT绑定路径="CaseName"FallbackValue="CaseName"/GT;LT/TextBlock.T而不是书面这样的属性:文本="{绑定路径=CaseName}"{S4}的干扰器|优秀!很高兴你发现你的解决方案。
干扰器 评论会员:
时间:有用的信息,感谢。无论如何,我想评论会员:
时间:很好的计划,以避免后面的代码在所有{五} !
干扰器 评论会员:
时间:!你怎么嘉宾
感谢非常鼓舞人心的文章!我有点新鲜WPF数据绑定,在UserControl的数据与模板类似的方式工作,但碰到了一个问题,我不能完全环绕我的头,也许别人可以吗?
我有一个UserControl,同样这个项目包含一个自定义的"进度条"(命名ProgressLine),这只是一个非常简单的网格两个矩形(一BG灰色,绿色FG,其宽度的另一个UserControl改为显示进度)。我也喜欢,因为我想,而不是正常的ProgressBar需要调整粗放式的代码较少。它的工作非常好,我才决定尝试用我的数据绑定UserControl的 - 从而改变属性DependecyProperty。现在,ProgressLine被创建时的属性设置两次 - 第一次在注册过程中的默认值,然后与正确的价值观在具有约束力的初始数据的第二次 - 但随后没有得到任何更多更新后,{。 BR}
我在我的主要的UserControl添加这样ProgressLine的:&src:ProgressLine Height="5" Maximum="{Binding Path=FileSize}"
Value="{Binding Path=CompletedSize}"
ToolTip="{Binding Path=PercentageCompletedString}" /&
ToolTip属性得到更新,但价值和Maximum属性没有(除非如前所述,数据绑定一次)。下面的代码背后的ProgressLine:
public partial class ProgressLine : UserControl
public ProgressLine() { InitializeComponent(); }
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register("Maximum", typeof(ulong), typeof(ProgressLine),
new PropertyMetadata((ulong)100));
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(ulong), typeof(ProgressLine),
new PropertyMetadata((ulong)0));
public ulong Maximum {
get { return (ulong)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); UpdateLineWidth(); }
public ulong Value {
get { return (ulong)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); UpdateLineWidth(); }
void UpdateLineWidth() {
ProgressLineForeground.Width = (ActualWidth * ((double)Value / Maximum));
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
UpdateLineWidth();
的数据源属性的公共ULONG属性,以匹配控制。在主的UserControl一切得到更新通知。我躲在一个极其丑陋的临时工作,围绕两个文本框,势必文本和补充的TextChanged事件,从ProgressLine是使用代码更新:
&TextBox Visibility="Collapsed" Text="{Binding Path=CompletedSize, Mode=OneWay}"
TextChanged="CompletedSizeChanged" /&
&TextBox Visibility="Collapsed" Text="{Binding Path=FileSize, Mode=OneWay}"
TextChanged="FileSizeChanged" /&
... ...它的工作原理确定,但必须有事可做,使其工作具有直接财产更新...
有人成立了我们的炸弹。你说什么!
,金评论会员:
时间:干扰器|嗯......将有一个想......现在有点忙!干扰器imgsrc=/upimg/_07_26_53_4.gif prasad02评论会员:
时间:哇超级干扰{五}5/5感谢和问候,普拉萨德 chaiguy1337评论会员:
时间:喜干扰机。伟大的文章,我也爱结合的UserControls作为DataTemplates。UserControls的其实是我在WPF封装的第一选择。不过,我不知道你可能会帮助我造成这种结合的一个棘手的问题:我想附加绑定绑定到一个封闭的文档(即,该文档包含的ItemsControl/ListBox的)的属性,作为一个DataTemplate的UserControl实例。问题是,当我使用的ElementName确定在包括文件,我要绑定到的元素,模板不能找到它,因为它在不同的"名称范围"的存在!我希望,因为你写的文章,您可能已经进入这个运行前。有什么想法?感谢,并有5P.S.爱SampleSort颜色计划-顶尖!这就是为什么我爱的WPF。{七}伤心,但真:4/3的美国人有困难与简单的分数。有10种人在这个世界上,那些能够理解的二进制那些不{O,O}OO(查看我的博客!)|)""???imgsrc=/upimg/_07_26_53_6.gif-??????{BR}干扰器|感谢章,
真的很高兴你喜欢的文章。约SampleSort,这是客气话表示感谢,是今年最热爱劳动至今。多多的乐趣使它,只是需要把它弄出来,有一些现在。
无论如何,有一些事情你可能要考虑这个问题,您不必的。首先是你真的必须检查WPF复合应用程序库,微软模式与实践偷看公布。其结构良好的松耦合的WPF应用程序的指导。你可以阅读它,并在这里获得:
我觉得在这个问题上为你调用的第一个港口,不过是用在您的具约束力的声明,如"FindAncestor":
{Binding Path=Property, RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}"
有了这样的东西,你也可以指定一个"AncestorLevel"。说你有一个列表框,您可以"在"第一个ListBox中像列表:
{Binding Path=Property, RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType="{x:Type ListBox}", AncestorLevel=2}"
有看看这个:
祝你好运!
干扰器 评论会员:
时间:我已经看了在复合应用程序的指导,甚至读了整篇文章解释它,它只是不罢工从长远来看是有益的东西我。这是完全反直觉的,注册一个容器之前,他们甚至可以使用的东西,而且所有的篮球必须突破只是使用它。坦白说,我看不出有任何指向它比其他附加测试工具。
咆哮预留芹苴,我给RelativeSource一试。 我知道我遇到这个问题前,但我真的砍的东西来得到它的工作(我依稀记得有DynamicResources定义和设置在代码隐藏等值)。
啊,现在我回头看,似乎我的解决方案,给外部文件比内部文档的不同名称。创建任何新的XAML文档时,我倾向于做的第一件事情之一是为它分配一个x:名称="这个",所以我可以访问当前对象(的XAML团队,海事组织监督),但问题模板的绑定与尊重用户控制(第一),不幸的是,我的情况有"本"的名称相同,因此,我们有位名称冲突的解决。 我的"解决方案"(或劈/解决方法)外的文件,这是不方便和痛苦,并在设计缺陷就我而言​​,使用不同的(唯一)名称。
如果我从一个XAML文件中引用的名称,它应该寻找这个名字,而不是控制定义模板文件包含文件。我会注意这使微软也许他们可以在未来的版本处理(或也许他们已经有了)。
反正抱歉打扰你,感谢提示。
RelativeSource也可能工作,但我觉得它的语法笨拙,至少可以说,我的ElementName更舒适。
欢呼声,洛根
伤心,但真:4 / 3的美国人有困难与简单的分数。
有10种人在这个世界上,那些能够理解的二进制那些不
{O,O} OO(查看我的博客!)|)""???
-??????{ BR}评论会员:
时间:为什么ListBox.ItemTemplate使用长形式?即
LT; ListBox的x:名称="peopleListBox"
LT; ListBox.ItemT
LT; D​​ataT
LT;的UserControls:ItemTemplateControl保证金="4"/ GT;
LT / DataT
LT / ListBox.ItemT
LT / ListB
相对于像的东西
LT; ListBox的x:名称="peopleListBox"
0; ItemTemplate中="{的StaticResource MyKeyNameForItemTemplateControl}"
此致, - 罗恩评论会员:
时间:干扰器|没有真正的理由。我认为它使事情更清晰虽然演示。干扰器(玻璃==Glass.Empty){GoToBarAndOrderMoreBeer();}{BR}其他{喝();}{BR}{五}imgsrc=/upimg/_07_26_53_4.gif joker797评论会员:
时间:嘿-第一关干扰器感谢这么多的这篇文章-这是一个我有很大的帮助我使用的是你在文章中所述的技术,并有一些TextBlock控件UserControl的模板的ListBox。看起来很相似,你我的ListBox的代码,但我已经添加了几个事件:LT;ListBox的名称="listCustomers"保证金="25,210,25,82"ListBoxItem.MouseDoubleClick="listCustomers_MouseDoubleClick"ListBoxItem.Selected="listCustomers_Selected"IsSynchronizedWithCurrentItem="真"的ItemContainerStyle="{的StaticResourceListBoxItemStretch}"GTLT;ListBox.ItemTLT;D​​ataT LT;GLT;控制:myListTemplateControl保证金="4"/GT;LT/G LT/DataTLT/ListBox.ItemTLT/ListBListBoxItem.MouseDoubleClick事件是发射没有问题,但ListBoxItem.Selected事件是不触发。你有任何想法为什么会吗?我有点难倒了-我不知道为什么一个ListBoxItem的事件会火,而不是其他再次感谢伟大的文章干扰器评论会员:
时间:!很高兴你喜欢的文章家伙BR}为了演示,只要做到以下几点:从这篇文章打开的演示,并取代与此MainWindow的构造函数:codeprespanclass="code-keyword"public/spanMainWindow(){InitializeComponent();peopleListBox.SelectionChanged+=spanclass="code-keyword"new/spanSelectionChangedEventHandler(peopleListBox_SelectionChanged);}/pre/code并添加以及...codeprespanclass="code-keyword"void/spanpeopleListBox_SelectionChanged(spanclass="code-keyword"object/spansender,SelectionChangedEventArgse){MessageBox.Show(spanclass="code-string""/spanspanclass="code-string"SelectedanItem"/span,spanclass="code-string""/spanspanclass="code-string"SelectionTest"/span,MessageBoxButton.OK);}/pre/code这应该得到你的方式!干扰器外出之前,已经在这里的每一个人!{五}imgsrc=/upimg/_07_26_53_4.gif joker797评论会员:
时间:感谢干扰器-你没有什么它应该做的以上概述代码我为什么会有ListBoxItem.Selected和未选中的事件,你可以把一个ListBox,切勿仍然没有进一步。我就必须解决它。这并不需要从您的文章,它的顶尖{五}干扰器评论会员:
时间:没问题!章有此阅读:imgsrc=/upimg/_07_26_53_13.gif特别是:要知道,当选择在ListBox变化,听SelectionChanged事件。ListBox中也有一个选择模式属性(单个,多个扩展),所以它不是简单的你首先可能会承担。干扰器外出之前,已经在这里的每一个人!{五}imgsrc=/upimg/_07_26_53_4.gif RNEELY评论会员:
时间:这似乎是最好的-如果不是唯一-的方式后面添加数据模板的代码。如果是的话,可能是这种方法的主要优点是可以看到在设计模板Expresson混合次要优势。它可以模拟在MicrosoftExpressionBlend的设计模式中的数据显示,在ExpressionBlend中的数据模板:imgsrc=/upimg/_07_26_53_15.gif]。然而,在这篇文章中提出的方法简单得多。再次感谢。此致,罗恩干扰器|可以肯定的,毫无疑问,这是可能的。但是像你说的话,你现在可以有一个DataTemplate代码!此外,如果你的数据在一个简单的格式,只是用一个"正常"的数据模板工作的情况是一样有效。
在Blend中使用"生成测试数据"的另一个问题是,你与更多的XAML结束! OK,它的一个微小的声明,但仍... {七}
外出之前,已经在这里的每一个人! {五}
评论会员:
时间:干扰器|想你可能会对我更新的DataTemplate文章后面的代码感兴趣......干扰器外出之前,已经在这里的每一个人!{五}imgsrc=/upimg/_07_26_53_4.gif RNEELY评论会员:
时间:大文章。感谢。有一个问题。什么优势(S)使用ProgressReporterUserControl的有超过一个DataTemplate中的UserControl使用一个普通的旧的ProgressBar的替代?此致,罗恩干扰器|!罗恩
在此DataTemplate的展示,演示一个简单的进度条会达到同样的事情。实质没有优势
&progressbar grid.column="2" value="{Binding Path=Progress}" /&
我包括ProgressReporter控制来说明如何您可能希望在封装的东西,使事情可重复使用的这个想法有点。对于初学者来说,这也说明你可以如何定义和使用自定义的依赖项属性提供燃料的"嵌入"用户控件。
另一个优势取决于你如何造型控制。它很容易为​​XAML文件变得非常大,难以管理,如果你想保持在他们艾滋病的过程中消耗的对象的XAML文件的样式。
干扰器外出之前,已经在这里的每一个人! {五}
评论会员:
时间:我喜欢这样,即使我知道如何做到这一点,但其良好的,不
萨沙理发微软的Visual C#MVP 2008Codeproject MVP 2008Your最好的朋友就是你。我是我最好的朋友。我们有着共同的看法,并未落认为
我的博客:{A19} 评论会员:
时间:干扰器|嘿萨沙,许多感谢的客气话!我花了很多时间阅读您的文章在WPF需要阅读IMO,很酷的东西。很高兴你喜欢这个小演示!干扰器外出之前,已经在这里的每一个人!{五}{A20}
&桌面&网页开发&移动开发&数据库&多媒体&编程语言&平台,框架和库&编程通用&图形/设计&开发周期&一般阅读&第三方产品&作者资源&其他
快速解答标签
价值作最多

我要回帖

更多关于 wpf controltemplate 的文章

 

随机推荐