2

私の問題はこれに少し似ています: TextBox コントロール テンプレートに問題がある

しかし、私はもう少し行きたいと思います:

私の問題は単純です: テンプレート化されたコントロール (ラベル、テキストボックス、チェックボックスなど) があります。各コントロールには、コントロール インスタンスのプロパティ値を設定することにより、実行時にすべてオーバーライドできるデフォルト値があります。また、プロパティに設定された値に関係なく、IsEnabled = false の場合に使用することにした値が優先されます。

今、私は、WPF の値の優先順位がこの動作の簡単な実装を妨げていることを知っています (別の質問で学んだように: http://msdn.microsoft.com/en-us/library/ms743230.aspx )

しかし、TextBox の Foreground プロパティを除いて、うまく機能する回避策を見つけることができました。(そしてこの特定のケースのみ)

したがって、フォアグラウンド値を処理するだけで、Label で行うことは次のとおりです: (より明確にするために、他のすべてのプロパティを削除しました)

    <Style TargetType="Label">
        <Setter Property="Foreground" Value="Blue"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Label">
                    <Border>
                        <ContentPresenter Name="ContentSite"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter TargetName="ContentSite" Property="TextBlock.Foreground" Value="Red"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

したがって、基本的に、デフォルトでは、Label には青色のテキストがあり、myLabel.Foreground = Brushes.Greenコード ビハインドで: を実行することで、たとえば緑色でオーバーライドできます。次に、何を設定しても、: と書くMyLabel.IsEnabled = Falseと、テキストは赤色になります。

そして、このテクニックはうまく機能します。(つまり、xaml のこの行は赤いテキストを出力します: <Label Foreground="Green" IsEnabled="False" />)。他のすべてのコントロールと同じように機能します。

しかし、これをテキストボックスで再現しようとすると、まったく機能しません。

ここに私のコードがあります:

    <Style TargetType="TextBox">
        <Setter Property="Foreground" Value="Blue"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TextBox">
                    <Grid>
                        <Border Name="Border">
                            <ScrollViewer x:Name="PART_ContentHost" />
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="PART_ContentHost" Property="Foreground" Value="Red"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Foreground="{TemplateBinding Foreground}"PART_ContentHostを追加しようとしましたが、成功しませんでした。

これは、PART_ContentHost がスクロールビューアーであり、何らかの非表示の (少なくとも私からは) 継承が行われているという事実と関係があると思われます。

私が見つけることができる他の唯一の説明は、TextBox クラスには、コントロール自体とその PART_ContentHost 部分 (バインディングまたは propertychanged イベントまたは何か他のもの?) の間のリンクをハードコーディングする特別な処理があるということです。

誰かが私にこれを説明できれば、これは素晴らしいことです! 誰かが素晴らしい解決策(私が現在使用しているもののような厄介なハックを含まないが、読者に重大な目の怪我を引き起こさないようにここには示さないもの)さえ提供できれば、これはさらに素晴らしいでしょう. !

4

1 に答える 1

4

デフォルトでは、その ScrollViewer 自体が次のようにテンプレート化されています。

<ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
    <Grid x:Name="Grid" Background="{TemplateBinding Background}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
        <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
        <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
    </Grid>
</ControlTemplate>

ちなみに、Blend を使用して TextBox から取得しました。

ScrollContentPresenterそのテンプレートにトリガーを追加するContentPresenterと、Label で行ったのと同じように機能することは間違いありません。

于 2011-06-01T14:10:58.827 に答える