• 正确理解ContentPresenter


    下图显示继承关系:

    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属性。

  • 相关阅读:
    自动化测试-02-Unittest-单元测试框架介绍
    自动化测试-01-cookie认识
    Java面试汇总
    多线程总结一:基本概念
    用Java编写你自己的简单HTTP服务器
    Spring高级事务管理难点剖析
    Http协议详解
    Java 互联网工程师要具备哪些技能或技术?
    架构师都要懂哪些知识
    java学习路线
  • 原文地址:https://www.cnblogs.com/shawnzxx/p/3346975.html
Copyright © 2020-2023  润新知