WPF:在ControlTemplate中使用TemplateBinding

A bit on TemplateBinding and how to use it inside a ControlTemplate.

Introductio

Today I‘ll try to write a bit on TemplateBinding and how to use it inside a ControlTemplate.TemplateBinding is a type of binding used mainly for template scenarios. Here I am not going to write more on its theoretical aspect as what is TemplateBinding, when to use, blah blah blah, as lot of content is readily available on the net.  So, let‘s start quickly with the coding part:

First of all, let‘s create a new project using WPF template and place a button in it as below:

Now, what I am going to do is, I am going to replace this content template for this button. So, in order to do this, open up the Button tag and add Button.Template markup tag with a new ControlTemplate as:

Now as soon as you will add ControlTemplate tag, you will notice that the content of the button is gone and button is shown as a transparent rectangle. This has happened because here I told WPF to replace the defaultControlTemplate with the one which I defined. But at this point, our ControlTemplate is blank, so there is no visualization and we can see only a transparent rectangle.

Now go ahead and customize our ControlTemplate by putting Ellipse inside it as:

Now we can see that we get a visualization for a button in the form of ellipse. At this point of time, it works OK, but there are scenarios where this struct breaks down.

For example, let‘s increase the height of button, from 35 to 105 as:

In the above image, you will notice that button height is increased but the ellipse size is still the same, which is a bad UI design. And the reason this is happening is, inside a ControlTemplate, the height of an ellipse is hard coded. So, no matter, whatever height is set at parent (i.e., Button), it will not get inherited to child control (i.e.Ellipse).

So, now we have to fix this problem by using a special type of binding called TemplateBinding insideControlTemplate. So, instead of hard coding the height, we will use TemplateBinding as shown below:

By setting the TargetType property of ControlTemplate, we are telling Ellipse that, any property of Button can be set to ellipse. Now, whatever the height of button will be, it will automatically be the height of ellipse also. Isn‘t it interesting?

Moving forward, let‘s do something more interesting with Fill property of ellipse.

In the above snippet, I am trying to set the Fill property of an ellipse using TemplateBinding. But now the problem here is, a button doesn‘t have a Fill property. So, there is no one-to-one mapping for Fillproperty. Now, what to do?

No need to worry that much because button does have a Background property as:

In the above image, you might have noticed that as soon as ellipse‘s Fill property is set to Background,ellipse becomes transparent as button‘s background. Now if we set button‘s Background property to Red, the same will be applied to ellipse too.

So, one can understand how much magic we can do with TemplateBinding.
Now, let‘s work a little bit on code cleanup.

ControlTemplate Inside Resource Dictionary

For better code readability, we will move out our ControlTemplate code and put it inside a resource dictionary as:

So, now we can see as earlier that whatever visual property for button is set, all get applied to ellipse as well.

Hope this tip was useful and gave you the basic idea on how to use TemplateBinding.

时间: 2024-07-30 04:22:41

WPF:在ControlTemplate中使用TemplateBinding的相关文章

年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了大量的复杂属性的设置. 在WPF中,设置外观样式我们有很多种方式,比如通过设置控件的属性来控制控件的外观样式:或者通过在每一个控件中分别设置Style:或者通过在整个Window.Resource中设置Style,又或者在App.xaml的Application.Resource设置Style. 在

WPF 在事件中绑定命令(可以在模版中绑定命令)

其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是如何构建使用的还不够,很多情况下我们都需要在某个事件触发的时候才去触发命令,所以将命令绑定到事件上是非常有效的做法,下面我们来接着实现将命令绑定到事件中. WPF实现命令绑定到事件 使用 System.Windows.Interactivity.dll 中的 Interaction 可以帮助我们实现

WPF在代码中创建DataTemplate时候的异常

今天写段程序用到了在代码中手动创建DataTemplate, var factory = new FrameworkElementFactory(typeof(OperationColumn));    returnnewDataTemplate() { VisualTree = factory }; 运行的时候出现如下异常: FrameworkElementFactory 必须位于此操作的密封模板中. 在 System.Windows.FrameworkElementFactory.Insta

【WPF】三维模型中的“照相机”

WPF 部分支持三维模型,为啥说是部分支持?毕竟 WPF 的侧重点还是在应用开发上,虽然也有些游戏是用 WPF 开发的,不过,老周想啊,如果真要开发游戏,最好用专门的框架,WPF 应当用于开发应用功能的.不过,动画.三维建模这些支持可以作为辅助,尤其是在 UI 上,适当地,可以增强一下.当然,不要为了装逼,弄得不伦不类的,那样就是主次不分了,现在有不少软件就是主次不分的. 在 WPF 中,要呈现三维模型,需要用到 Viewport3D ,它是三维对象的总容器,所有三维对象都应该放在这个容器中.本

在WPF应用程序中使用Font Awesome图标

Font Awesome 在网站开发中,经常用到.今天介绍如何在WPF应用程序中使用Font Awesome . 如果是自定义的图标字体,使用方法相同. 下载图标字体 在官方网站或github上下载资源 http://fontawesome.io/#modal-download https://github.com/FortAwesome/Font-Awesome 解压下载的文件(我是在github上下载的源码),我们要使用的是其中css和fonts文件夹中的内容 在项目中加入字体 新建WPF应

WPF 显示文件列表中使用 ListBox 变到ListView 最后使用DataGrid

WPF 显示文件列表中使用 ListBox 变到ListView 最后使用DataGrid 故事背景: 需要检索某目录下文件,并列出来,提供选择和其他功能. 第一版需求: 列出文件供选择即可,代码如下: <ListBox Name="multiSelectFileLst" ItemsSource="{Binding FileList}" Grid.Row="1" Grid.Column="1" > <List

WPF 在事件中绑定命令

导航:MVVMLight系列文章目录:<关于 MVVMLight 设计模式系列> 其实这也不属于MVVMLight系列中的东东了,没兴趣的朋友可以跳过这篇文章,本文主要介绍如何在WPF中实现将命令绑定到事件中. 上一篇中我们介绍了MVVMLight中的命令的用法,那么仅仅知道命令是如何构建使用的还不够,很多情况下我们都需要在某个事件触发的时候才去触发命令,所以将命令绑定到事件上是非常有效的做法,下面我们来接着实现将命令绑定到事件中. WPF实现命令绑定到事件 使用 System.Windows

WPF: 在MVVM中使用Navigtaion

Navigation可以很方便的在页面间进行切换,但是在MVVM模式下,使用Naviation会有一个问题,切换的逻辑需要在ViewModel层完成,但是Navigation需要知道页面的实例或者Uri才能进行切换,那我们如何在ViewModel与UI分离的情况下,用Navigation完成页面的切换呢? 假如有一个程序如下所示,点击Switch之后会从Summary Page切换到另一个页面Detail Page: 在MVVM中,我们需要有三个ViewModel,一个是SummaryViewM

WPF窗体视图中绑定Resources文件中字符串时,抛出:System.Windows.Markup.StaticExtension

问题描述: 在Resources.resx定义了一个静态字符串字段Title,并在WPF窗体视图中绑定为窗体的标题: Title="{x:Static local:Resources.Title}" 但是,在运行应用时,抛出System.Windows.Markup.StaticExtension异常. 原因: 解决方案: 将Resources.resx的访问修饰符由internal修改为public.