正确理解ContentPresenter
下圖顯示繼承關系:
ContentControl:Control (在Control類並沒有Content屬性, 所以在這之上再寫了一個ContentControl, 使控件有Content屬性可以顯示內容)
ContentPresenter:FrameworkElement (ContentPresenter一般用在CT里負責把Control指定的Content顯示出來)
Control:FrameworkElement
ItemsControl:Control
ItemsPresenter:FrameworkElement
?
接著來我們看一下實例:
使用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}"/>
結果:
?
如果用Content來綁定Header屬性:
<ContentPresenter Content="{TemplateBinding Header}"/>
那么你還得再次綁定ContentStringFormat,ContentTemplate和ContentTemplateSelector屬性,所以記住總是用ContentPresenter.ContentSource屬性。
?
WPF:為什么使用ContentPresenter.ContentSource而不是Content屬性?
wpf控件開發基礎(1)
轉WPF的Presenter(ContentPresenter)轉載于:https://www.cnblogs.com/shawnzxx/p/3346975.html
總結
以上是生活随笔為你收集整理的正确理解ContentPresenter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 活在当下的经典句子237个
- 下一篇: Oracle中视图的创建和处理方法