2011-10-17 11 views
4

トリガーされたセッターが有効になる前に、スタイルにデフォルトのセッターが必要な依存プロパティーがあるのはなぜですか?例えばDataTriggerが有効になる前に、スタイルで定義されているデフォルトを必要とするプロパティがあるのはなぜですか?

<ContentControl> 

    <ContentControl.Resources> 
     <DataTemplate x:Key="DefaultTemplate"> 
      <TextBlock Text="Default Template" /> 
     </DataTemplate> 
     <DataTemplate x:Key="MouseOverTemplate"> 
      <TextBlock Text="MouseOver Template" /> 
     </DataTemplate> 
    </ContentControl.Resources> 

    <ContentControl.Style> 
     <Style TargetType="{x:Type ContentControl}"> 

      <!-- Triggered setter will work without this default setter --> 
      <!--<Setter Property="ContentTemplate" 
         Value="{StaticResource DefaultTemplate}" />--> 

      <Style.Triggers> 
       <Trigger Property="IsMouseOver" Value="True"> 
        <Setter Property="ContentTemplate" 
          Value="{StaticResource MouseOverTemplate}" /> 
       </Trigger> 
      </Style.Triggers> 

     </Style> 
    </ContentControl.Style> 

</ContentControl> 

私はどこかの良い説明を見ましたが、私はどこ覚えていないことができます。 the order that WPF applies dependency property valuesと何か関係がありますが、詳細を覚えていないか、トリガーが有効になる前にデフォルトで定義されているプロパティが必要な理由があります。

答えて

1

あなたの最初のStyleが動作しない場合、私はあなたのContentControlが同じように定義されていない限り、非常に驚​​くだろう。もしそうなら

<ContentControl ContentTemplate="{StaticResource DefaultTemplate}" /> 

、それは価値の優先順位としなければならないでしょう。あなたのリンクから、私の例のような設定は#3にあります。したがって、それをオーバーライドできる唯一のものは、アニメーションか、値が強制された場合です。 StyleまたはControlTemplate(存在する場合)は、ContentControl.ContentTemplateプロパティを変更できませんでした。あなたの二Style

、あなたがそうのようなあなたのContentControlを定義することができます。この場合

<ContentControl /> 

DefaultTemplateためSetterは、(彼らは#6であるとして)ので、トリガーは、それを上書きすることができます。#8であります。あなたが持っていることを、改めて仮定し

<ContentControl ContentTemplate="{StaticResource DefaultTemplate}" /> 

はそれからControlTemplateで使用DataTemplateを上書きすることは可能ですが、ContentControl.ContentTemplateの値を変更することはできません。ような何か:それは効果的ContentControl.ContentTemplateプロパティを無視してここ

<Style TargetType="{x:Type ContentControl}"> 
    <Setter Property="ControlTemplate"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ContentControl}"> 
       <ContentPresenter x:Name="presenter" /> 
       <ControlTemplate.Triggers> 
        <DataTrigger Binding="{Binding SomeProperty}" Value="A"> 
         <Setter TargetName="presenter" Property="ContentTemplate" Value="{StaticResource TemplateA}" /> 
        </DataTrigger> 
        <DataTrigger Binding="{Binding SomeProperty}" Value="B"> 
         <Setter TargetName="presenter" Property="ContentTemplate" Value="{StaticResource TemplateB}" /> 
        </DataTrigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

は、我々はのContentPresenterが使用するDataTemplateを切り替えます。

あなたのアップデートに基づいて、マウスが "上"になることはありません。 ContentControlは何もレンダリングしていません(透明ピクセルでさえない)ので、マウスイベントを受け取らないでしょう。

<Style TargetType="{x:Type ContentControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ContentControl}"> 
       <Border Background="{TemplateBinding Background}"> 
        <ContentPresenter /> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 

    <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter Property="ContentTemplate" Value="{StaticResource MouseOverTemplate}" /> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

そして、あなたはContentControlに上の背景=「透明」に設定する必要があるだろうが:あなたはそれを修正するために、このような何かを行うことができます。

+0

最初のスタイルは機能しません。シンプルな 'IsMouseOver'トリガーで試してみてください。 – Rachel

+0

@Rachel - どのようにそのトリガーを定義していますか?これは、DataContextに当てはまる '{Binding IsMouseOver}'では動作しませんが、{Binding IsMouseOver、RelativeSource = {RelativeSource Self}} 'のように動作します。 – CodeNaked

+0

コピー/貼り付け可能なコードで質問を更新しました – Rachel

関連する問題