2011-03-03 7 views
7

HyperlinkForegroundの色を設定しようとしていますが、祖先のResourcesにあるStyleオブジェクトを使用しても効果はありません。私もBasedOnのチップをChanging Hyperlink foreground without losing hover colorから使用しましたが、それは何の違いもありません - 私はまだホバーに赤い青のハイパーリンクを取得します。DataTemplate内のハイパーリンクにスタイルを伝播する方法は?

<StackPanel Background="Red" TextElement.Foreground="White"> 
    <StackPanel.Resources> 
    <Style TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}"> 
     <Setter Property="Foreground" Value="Yellow"/> 
     <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter Property="Foreground" Value="White"/> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </StackPanel.Resources> 
    <TextBlock>Data import errors</TextBlock> 
    <ItemsControl ItemsSource="{Binding Errors}"/> 
</StackPanel> 

そしてItemsControlの項目は、次のDataTemplateを拾っています:ここで

は、その項目のハイパーリンクを使用して示されているItemsControlを含め、私のコントロールのXAMLです

<DataTemplate DataType="{x:Type Importer:ConversionDetailsMessage}"> 
    <TextBlock> 
    <Run Text="{Binding Message, Mode=OneTime}"/> 
    <Hyperlink Command="Common:ImportDataCommands.ExplainConversionMessage" CommandParameter="{Binding}"> 
     <Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/> 
    </Hyperlink> 
    </TextBlock> 
</DataTemplate> 

にですDataTemplateHyperlinkに色々な色を直接設定したくないという点にも留意する価値があります。これは、によってテンプレートが使用され、異なるItemsControlオブジェクトの数字であり、そのほとんどは白い背景にあるため、標準のハイパーリンクカラーを使用できます。ただし、上記のXAMLの背景に赤い背景があることに注意してください。

要するに、DataTemplateは、使用されているコントロールについて何も知る必要はありません。テンプレートのコントロールのスタイルは、それをフィルタリングするだけです。

だから誰も私のスタイルをフィルタリングしない理由と私はそれを修正するために何ができるのか教えていただけますか?

ありがとうございました。

アップデート:私は私の生産アプリで動作するようにパブロの答えを得ることができなかったので、私は以来、別のテストアプリでそれを試してみた
。このアプリはWinFormsアプリケーションで、メインフォームにはElementHost以外は何も含まれておらず、それ自体には単純なWPFユーザーコントロールが含まれています。ここではそのXAMLです:

<UserControl x:Class="DataTemplateStyling.StylingView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:DataTemplateStyling="clr-namespace:DataTemplateStyling" 
      x:Name="root" Loaded="StylingViewLoaded"> 

    <UserControl.Resources> 
    <Style x:Key="MyDefaultHyperlinkStyle" BasedOn="{StaticResource {x:Type Hyperlink}}"/> 

    <DataTemplate DataType="{x:Type DataTemplateStyling:ImportMessage}"> 
     <DataTemplate.Resources> 
     <Style TargetType="{x:Type Hyperlink}" 
       BasedOn="{StaticResource MyDefaultHyperlinkStyle}"/> 
     </DataTemplate.Resources> 
     <TextBlock> 
     <Run Text="{Binding Message, Mode=OneTime}"/> 
     <Hyperlink NavigateUri="{Binding HelpLink.Item1}"> 
      <Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/> 
     </Hyperlink> 
     </TextBlock> 
    </DataTemplate> 
    </UserControl.Resources> 

    <Grid DataContext="{Binding ElementName=root}"> 
    <StackPanel Background="Red" TextElement.Foreground="White"> 
     <StackPanel.Resources> 
     <Style x:Key="MyDefaultHyperlinkStyle" TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}"> 
      <Setter Property="Foreground" Value="Yellow"/> 
      <Style.Triggers> 
      <Trigger Property="IsMouseOver" Value="True"> 
       <Setter Property="Foreground" Value="White"/> 
      </Trigger> 
      </Style.Triggers> 
     </Style> 
     </StackPanel.Resources> 
     <TextBlock>Data import errors</TextBlock> 
     <ItemsControl ItemsSource="{Binding Messages}"/> 
    </StackPanel> 
    </Grid> 
</UserControl> 

それは述べ、これはInvalidOperationExceptionを生成し、上記現状では「基本型であるターゲット・タイプとスタイルにすることができる唯一の基本 『をIFrameworkInputElement』。」

これは、UserControl.Resources要素のすぐ内側のStyle定義にTargetType="Hyperlink"を入れることで修正できます。メッセージが表示されているが、それらのリンク部分がまだデフォルト青いハイパーリンクのスタイルを持っているしかし、:要するに

Blue hyperlinks persist

、それは働いていないので、私は他の提案/訂正を歓迎するだろう。 :(

アップデート2:
パブロから代替ソリューションのおかげで、それは今作業です:)

答えて

7

いくつかは、グーグルの後、私はこの記事に走った:http://www.11011.net/archives/000692.html

それはそこに記載されているように、それは(TextBlockHyperlinkなど)Control由来ではない要素がDataTemplate境界の外側の暗黙的なスタイルを見ていないことが判明。

また、記事で言われているように、考えられる回避策は、スタイルキーを明示的に指定することです。

<DataTemplate DataType="{x:Type Importer:ConversionDetailsMessage}"> 
    <DataTemplate.Resources> 
    <Style TargetType="{x:Type Hyperlink}" 
      BasedOn="{StaticResource MyDefaultHyperlinkStyle}"/> 
    </DataTemplate.Resources> 
    <TextBlock> 
    <Run Text="{Binding Message, Mode=OneTime}"/> 
    <Hyperlink Command="Common:ImportDataCommands.ExplainConversionMessage" CommandParameter="{Binding}"> 
     <Run Text="{Binding HelpLink.Item2, Mode=OneTime}"/> 
    </Hyperlink> 
    </TextBlock> 
</DataTemplate> 

とデータテンプレート理由:次に、あなただけのDataTemplate資源で私たちの名前のスタイルを参照するHyperlinkの暗黙的なスタイルを追加することができます

<StackPanel Background="Red" TextElement.Foreground="White"> 
    <StackPanel.Resources> 
    <Style x:Key="MyDefaultHyperlinkStyle" TargetType="Hyperlink" BasedOn="{StaticResource {x:Type Hyperlink}}"> 
     <Setter Property="Foreground" Value="Yellow"/> 
     <Style.Triggers> 
     <Trigger Property="IsMouseOver" Value="True"> 
      <Setter Property="Foreground" Value="White"/> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </StackPanel.Resources> 
    <TextBlock>Data import errors</TextBlock> 
    <ItemsControl ItemsSource="{Binding Errors}"/> 
</StackPanel> 

:あなたのケースでは、このようなものかもしれません親コンテナがキー "MyDefaultHyperlinkStyle"を持つスタイルを定義していない可能性があります。この場合、リソース "MyDefaultHyperlinkStyle"が見つからないという例外がスローされます。

<Style x:Key="MyDefaultHyperlinkStyle" 
     BasedOn="{StaticResource {x:Type Hyperlink}}/> 

更新:

あなたのアップデートに含まれるコードがあるため動作しませんこの問題に対処するために、あなただけのApp.xamlのどこかにデフォルトのスタイルを継承するようなキーとスタイルを定義することができます日付テンプレートで次のリソースを参照することを意味静的リソースの性質上、の...

BasedOn="{StaticResource MyDefaultHyperlinkStyle}" 

...常に次のリソース(デフォルトのスタイルである)を指すようになります:

<Style x:Key="MyDefaultHyperlinkStyle" BasedOn="{StaticResource {x:Type Hyperlink}}"/> 

スタティックリソース参照はコンパイル時に解決されるため、ツリー内の最も近いリソースが使用されます。

DynamicResourceを使用するように誘惑されるかもしれませんが、残念ながらBasedOnプロパティではサポートされていません。

プロパティは動的リソースをサポートしているので、スタイル内で使用するブラシで同じトリックを使用できます。ここでは、動的ブラシを使用するように変更テストユーザーコントロールがある:彼らは青になります外ながら、期待どおりに動作します

<UserControl x:Class="DataTemplateStyling.StylingView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:DataTemplateStyling="clr-namespace:DataTemplateStyling" 
      x:Name="root" 
      Loaded="StylingViewLoaded"> 

    <UserControl.Resources> 
     <SolidColorBrush x:Key="HyperlinkForeground" 
         Color="Blue" /> 

     <SolidColorBrush x:Key="HyperlinkHoverForeground" 
         Color="Gray" /> 

     <Style x:Key="MyDefaultHyperlinkStyle" 
       TargetType="Hyperlink" 
       BasedOn="{StaticResource {x:Type Hyperlink}}"> 
      <Setter Property="Foreground" 
        Value="{DynamicResource HyperlinkForeground}" /> 
      <Style.Triggers> 
       <Trigger Property="IsMouseOver" 
         Value="True"> 
        <Setter Property="Foreground" 
          Value="{DynamicResource HyperlinkHoverForeground}" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 

     <DataTemplate DataType="{x:Type DataTemplateStyling:ImportMessage}"> 
      <DataTemplate.Resources> 
       <Style TargetType="{x:Type Hyperlink}" 
         BasedOn="{StaticResource MyDefaultHyperlinkStyle}" /> 
      </DataTemplate.Resources> 
      <TextBlock> 
       <Run Text="{Binding Message, Mode=OneTime}" /> 
       <Hyperlink NavigateUri="{Binding HelpLink.Item1}"> 
        <Run Text="{Binding HelpLink.Item2, Mode=OneTime}" /> 
       </Hyperlink> 
      </TextBlock> 
     </DataTemplate> 
    </UserControl.Resources> 

    <Grid DataContext="{Binding ElementName=root}"> 
     <StackPanel Background="Red" 
        TextElement.Foreground="White"> 
      <StackPanel.Resources> 
       <SolidColorBrush x:Key="HyperlinkForeground" 
           Color="Yellow" /> 

       <SolidColorBrush x:Key="HyperlinkHoverForeground" 
           Color="White" /> 
      </StackPanel.Resources> 
      <TextBlock>Data import errors</TextBlock> 
      <ItemsControl ItemsSource="{Binding Messages}" /> 
     </StackPanel> 
    </Grid> 
</UserControl> 

StackPanel内側、すなわちすべてのリンク、イエロー/ホワイトになります。

これが役に立ちます。

+0

すごいグーグルスキル - ありがとう!そして、非常に完全な答えです。私はこれを試してみて、それを受け入れたらそれをマークします。 –

+0

私のアプリは 'ElementHost'を使ったWinFormsアプリなので、app.xamlファイルはありません。それでも私の 'UserControl'のリソース辞書に空の' MyDefaultHyperlinkStyle'を 'DataTemplate'の直前に追加し、上記の特定の' StackPanel'を残して独自の定義に置き換えました。残念ながら、まだ動作していません。私は物事を試していきます... –

+0

@Mal - データテンプレート自体にスタイルを含めることを忘れませんでしたか?