1. 程式人生 > >WPF:為什麼使用ContentPresenter.ContentSource而不是Content屬性?

WPF:為什麼使用ContentPresenter.ContentSource而不是Content屬性?

因為ContentPresenter.ContentSource比Content屬性加一個TemplateBinding看起來更方便?不僅僅是這些,實際上如果用ContentSource的話,Content相關的屬性比如ContentStringFormat,ContentTemplate和ContentTemplateSelector都會被自動設定,而如果用Content加TemplateBinding,你必須手動將上述屬性繫結到ContentPresenter上。

  比如使用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屬性。