zoukankan      html  css  js  c++  java
  • 正确理解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属性。

  • 相关阅读:
    vue项目打包后css背景图路径不对的问题
    Vue项目图片剪切上传——vue-cropper的使用
    Vue项目使用AES做加密
    VUE滚动条插件——vue-happy-scroll
    自实现jQuery版分页插件
    HTML5中的Web Notification桌面通知
    img标签实现和背景图一样的显示效果——object-fit和object-position
    自实现PC端jQuery版轮播图
    web前端几个小知识点笔记
    限制可编辑div只能输入纯文本
  • 原文地址:https://www.cnblogs.com/shawnzxx/p/3346975.html
Copyright © 2011-2022 走看看