首页 > 其他分享 >wpf特殊属性:正确理解ContentPresenter(转载)

wpf特殊属性:正确理解ContentPresenter(转载)

时间:2023-06-14 22:11:22浏览次数:60  
标签:屬性 ContentSource ContentPresenter Content ContentTemplateSelector wpf ContentStr

原文地址:https://www.cnblogs.com/shawnzxx/p/3346975.html

下图显示继承关系:

ContentControl:Control (在Control類並沒有Content屬性, 所以在這之上再寫了一個ContentControl, 使控件有Content屬性可以顯示內容)

ContentPresenter:FrameworkElement (ContentPresenter一般用在CT里负责把Control指定的Content显示出来)

Control:FrameworkElement

ItemsControl:Control

ItemsPresenter:FrameworkElement

ScreenClip

 

接著來我們看一下實例:

使用ContentPresenter

            <ContentControl Content="YangMark">
                <ContentControl.Template>
                    <ControlTemplate TargetType="ContentControl">
                        <ContentPresenter/>
                    </ControlTemplate>
                </ContentControl.Template>
            </ContentControl>

輸出結果: YangMark
正確顯示Content!!
 
不使用ContentPresenter
            <ContentControl Content="YangMark">
                <ContentControl.Template>
                    <ControlTemplate TargetType="ContentControl">
              <ContentPresenter/>
                    </ControlTemplate>
                </ContentControl.Template>
            </ContentControl>
 
輸出結果:      
無法顯示出Content!!

結論1:ContentPresenter通常出現在ControlTemplate內,且若不使用ContentPresenter則Content屬性就無法正常顯示。

 
實例2:ContentPresenter中的ContentSource屬性
為什麼只為了顯示出Content屬性要大費周張弄出ContentPresenter呢??
我們可以先比較以下兩種代碼不同之類,
            <ContentControl Content="YangMark" ContentStringFormat="Hello!! {0}">
                <ContentControl.Template>
                    <ControlTemplate TargetType="ContentControl">
                        <ContentPresenter ContentSource="Content"/>
                    </ControlTemplate>
                </ContentControl.Template>
            </ContentControl>

輸出結果:Hello!! YangMark  
            <ContentControl Content="YangMark" ContentStringFormat="Hello!! {0}">
                <ContentControl.Template>
                    <ControlTemplate TargetType="ContentControl">
                        <ContentPresenter Content="{TemplateBinding Content}"/>
                    </ControlTemplate>
                </ContentControl.Template>
            </ContentControl>

 

輸出結果:YangMark
僅出現Content屬性的內容!!
 
結論2:<ContentPresenter/>與<ContentPresenter ContentSource="Content"/> 意義上是相同的。

写ContentSource它們同時綁定了Content, ContentStringFormat, ContentTemplate和ContentTemplateSelector等內容

若僅用Content="{TemplateBinding Content}"代表只綁定Content屬性而已,还要手动绑定其他ContentStringFormat, ContentTemplate和ContentTemplateSelector等。

 

實例3:ContentSource的應用

 以HeaderContentControl為例,使用ContentPresenter綁定內容屬性。
            <HeaderedContentControl Header="Header" HeaderStringFormat="I'm {0}"
                                    Content="Content" ContentStringFormat="I'm {0}">
                <HeaderedContentControl.Template>
                    <ControlTemplate TargetType="HeaderedContentControl">
                        <DockPanel>
                            
                            <ContentPresenter ContentSource="Header" DockPanel.Dock="Top"></ContentPresenter>
                            
                            <!--等同於<ContentPresenter ContentSource="Content"/>-->
                            <ContentPresenter></ContentPresenter>
                            
                        </DockPanel>
                    </ControlTemplate>
                </HeaderedContentControl.Template>
            </HeaderedContentControl>


輸出結果:

I'm Header

I’m Content

 

結論3:ContentSource若指定對象為Content是可以省略的,若不為Content(如:Header)則不能省略。

 

 

總結:

Content, ContentStringFormat, ContentTemplate和ContentTemplateSelector等屬性, 我將它們稱為內容屬性.

1. ContentPresenter的作用就是用來顯示內容屬性

2.ContentSource若指定對象為Content,則等同於<ContentPresenter/>; 若指定對象不為Content,

   則必須使用ContentSource聲明指定的對象.

 

參考資料:

比如使用ContentPresenter的ContentSource,然后在ContentControl中设置ContentStringFormat:

<Window.Resources>

    <Style TargetType="ContentControl">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="ContentControl">

                    <!-- 这里等价于直接<ContentPresenter /> -->

                    <!-- 强调一下直接用ContentPresenter其ContentSource属性为Content -->

                    <ContentPresenter ContentSource="Content"/>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>

</Window.Resources>

<ContentControl ContentStringFormat="你好:{0}">Mgen</ContentControl>

结果会输出:你好:Mgen。

 

如果把上面ContentPresenter改用TemplateBinding绑定ContentControl的Content属性:

<ContentPresenter Content="{TemplateBinding Content}"/>

结果只会输出:Mgen。

 

此时其实ContentStringFormat,ContentTemplate和ContentTemplateSelector都不会管用的,那么只能再用TemplateBinding都把他们在ContentPresenter中绑定好:

<ContentPresenter Content="{TemplateBinding Content}"

                 ContentStringFormat="{TemplateBinding ContentStringFormat}"

                 ContentTemplate="{TemplateBinding ContentTemplate}"

                 ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>

当然ContentPresenter不仅限于ContentControl,可以用在任何类似ContentControl.Content这样的控件属性中,比如HeaderedContentControl.Header属性。

 

这样定义HeaderedContentControl的控件模板:

<Style TargetType="HeaderedContentControl">

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="HeaderedContentControl">

                <DockPanel>

                    <Border DockPanel.Dock="Top">

                        <ContentPresenter ContentSource="Header"/>

                    </Border>

                    <!-- 等于:<ContentPresenter ContentSource="Content"/> -->

                    <ContentPresenter/>

                </DockPanel>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

 

示例:

<HeaderedContentControl Header="Header"

                       Content="Content"

                       HeaderStringFormat="上:{0}"

                       ContentStringFormat="下:{0}"/>

结果:

image

 

如果用Content来绑定Header属性:

<ContentPresenter Content="{TemplateBinding Header}"/>

那么你还得再次绑定ContentStringFormat,ContentTemplate和ContentTemplateSelector属性,所以记住总是用ContentPresenter.ContentSource属性。

 

WPF:为什么使用ContentPresenter.ContentSource而不是Content属性?

wpf控件开发基础(1)

转WPF的Presenter(ContentPresenter)

标签:屬性,ContentSource,ContentPresenter,Content,ContentTemplateSelector,wpf,ContentStr
From: https://www.cnblogs.com/shuaimeng/p/17481493.html

相关文章

  • WPF之浅谈数据模板(DataTemplate)
    数据模板有什么用简而言之,数据模板能让你更方便、更灵活的显示你的各类数据。只有你想不到,没有它做不到的(感觉有点夸张,实践之后,你就觉得一点不夸张......
  • WPF在win10/11上启用模糊特效 适配Dark/Light Mode
    先看效果图win11:win10: 大佬们已经总结了许多在WPF上开启亚克力效果的方法,本文只是做一些填坑和适配工作.正文开始先来看看部分版本Windows的模糊效果和我的适配方案:1).早期Windows10:SetWindowCompositionAttribute方法参照:在Windows10上为WPF窗口添加模糊特......
  • wpf combobox 绑定枚举
    1、先定义个枚举转换类///<summary>///枚举转换///</summary>publicclassEnumerationExtension:MarkupExtension{privateType_enumType;///<summary>///枚举转换///</summary>///<param......
  • WPF之资源
    静态资源(StaticResource):指的是在程序载入内存时对资源的一次性使用,之后就不再去访问这个资源了。动态资源使用(DynamicResource):指的是在程序运行过程中仍然会去访问资源。在网上看了一些介绍,不能实现,或许是我VS版本的问题,于是自己改动了一些。代码1:在Window的资源里放置两个TextBloc......
  • Winform/WPF Clipboard之剪切复制粘贴
    转载自作者:心存善念本文地址:https://www.cnblogs.com/xcsn/p/4678364.htmWinform///<summary>///复制粘贴帮助类///</summary>publicclassClipboardHelper{///<summary>///复制到剪切板///</summary>//......
  • WPF 绑定command在触屏上操作时,即使点中button也可能不触发
    现象:WPF程序绑定的command在触摸屏上,点击button后,button绑定的事件偶尔会出现不响应的情况。确认100%点击有效,不会出现误触的情况。但是用鼠标点击,绝对不会出现这种现象。 原因:在非触屏环境,bingdingcommand是由点击来触发,即是使用鼠标等输入设备来执行点击触发command,调用......
  • WPF控件库之HandyControl
    HandyControl介绍HandyControl是一套WPF控件库,它几乎重写了所有原生样式,同时包含80余款自定义控件(正逐步增加)。安装使用github地址:https://github.com/HandyOrg/HandyControl官网地址:https://handyorg.github.io/......
  • WPF 入门笔记 - 03 - 样式基础
    ......
  • WPF控件库之Syncfusion
    参考文章:https://www.cnblogs.com/zh7791/p/14009262.htmlhttps://www.cnblogs.com/DotNeter-Hpf/p/16523758.htmlhttps://www.cnblogs.com/redmoon/p/4420942.htmlSyncfusion介绍Syncfusion提供了一个由兼容的开发人员控制套件,可嵌入的BI平台和业务软件组成的生态系统。它......
  • WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(5)
    WPF入门教程系列目录WPF入门教程系列二——Application介绍WPF入门教程系列三——Application介绍(续)WPF入门教程系列四——Dispatcher介绍WPF入门教程系列五——Window介绍WPF入门教程系列十一——依赖属性(一)WPF入门教程系列十五——WPF中的数据绑定(一)  添加Cl......