Почему некоторым свойствам требуется значение по умолчанию, определенное в стиле, прежде чем DataTrigger вступит в силу? - PullRequest
4 голосов
/ 17 октября 2011

Почему некоторые свойства зависимостей должны иметь установщик по умолчанию в стиле, чтобы сработавшие установщики вступили в силу?

Например,

<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>

Я видел хорошее объяснение где-то, но не могу вспомнить, где. Я помню, что это было как-то связано с порядком, в котором WPF применяет значения свойств зависимостей , но я не могу вспомнить детали или почему некоторые свойства требуют определения по умолчанию, прежде чем сработают триггеры, а другие - нет. .

1 Ответ

1 голос
/ 17 октября 2011

Я был бы очень удивлен, если бы ваш первый Style не работал, если ваш ContentControl не определен как:

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

Если так, то это будет связано с приоритетом значения.По вашей ссылке настройка, как в моем примере, будет на # 3.Таким образом, единственное, что могло бы переопределить это, было бы анимацией или если значение было приведено.Ни Style, ни ControlTemplate (если есть) не могут изменить свойство ContentControl.ContentTemplate.

Со вторым Style вы можете определить свой ContentControl следующим образом:

<ContentControl />

В этом случае Setter для DefaultTemplate находится на # 8, поэтому триггеры могут переопределить его (как на # 6).

Снова предположим, что у вас есть:

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

Тогда можно переопределить DataTemplate, используемый в ControlTemplate, но вы не можете изменить значение 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>

Здесь мы переключаем DataTemplate, используемый ContentPresenter, чтобы он эффективно игнорировал свойство ContentControl.ContentTemplate.

Однако, исходя из ваших обновлений, ничего не нужно длямышь должна быть «над».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>

И вам нужно установить Background = "Transparent" в ContentControl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...