Изменить стиль TextBlock для TargetNullValue - PullRequest
4 голосов
/ 02 марта 2012

Я хочу изменить стиль TextBlock, если значение свойства привязки равно нулю. Я указал значение для TargetNullValue TextBlock, которое будет отображаться, но я хочу отобразить его в альтернативном стиле. Как я могу это сделать.

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

Текущее решение:

<TextBlock Visibility="{Binding MyText, Converter={StaticResource nullToVisibilityConverter}}"
           FontSize="20"
           Foreground="Black"
           Text="{Binding MyText}" />

<TextBlock Visibility="{Binding MyText, Converter={StaticResource nullToVisibilityConverter}}"
           FontSize="20"
           FontStyle="Italic"
           Foreground="Gray"
           Text="None" />

Необходимое решение:

<TextBlock FontSize="20"
           Foreground="Black"
           Text="{Binding MyText, TargetNullValue='None'}" />

<!-- plus any styles, templates or triggers, to change style of TextBlock for TargetNullValue -->

Как я могу использовать альтернативный стиль для TargetNullValue. Любые решения, использующие стили, триггеры или шаблоны, приветствуются.

1 Ответ

1 голос
/ 09 апреля 2012

Примечание: это для WPF, вам, возможно, придется конвертировать все, что не совсем совпадает с SL5.0.

Самое простое решение (если это требование не является вездесущим) - это создать специальный стиль длякаждый экземпляр, который привязывается к тому же свойству, что и текстовый блок, проверяет наличие Null и устанавливает там свойства.

Этот пример будет вставлен в Kaxaml.

  <Style x:Key="tacoStyle" TargetType="TextBlock">
    <Style.Triggers>
      <DataTrigger Binding="{Binding Source={StaticResource taco}}" Value="{x:Null}">
        <Setter Property="Foreground" Value="Red"/>
      </DataTrigger>
    </Style.Triggers>
  </Style>
</StackPanel.Resources>
<TextBlock Style="{StaticResource tacoStyle}" Text="{Binding Source={StaticResource taco}, TargetNullValue='bacon'}"/>

Конечно, если вам нужно более общее решение, вы можете расширить TextBlock и добавить некоторую логику для обработки этого.

<StackPanel>
        <StackPanel.Resources>
            <x:NullExtension x:Key="taco"/>
            <Style x:Key="AltTacoStyle" TargetType="yourNS:ExtendedTextBlock">
                <Setter Property="Foreground" Value="Pink"/>
            </Style>
        </StackPanel.Resources>
        <yourNS:ExtendedTextBlock Text="{Binding Source={StaticResource taco}, TargetNullValue='bacon'}"
                                                                                AltStyle="{StaticResource AltTacoStyle}"
                                                                                AllowAltStyleOnNull="True"/>
    </StackPanel>

И контроль:

    public class ExtendedTextBlock : TextBlock {


    public static readonly DependencyProperty AllowAltStyleOnNullProperty =
        DependencyProperty.Register("AllowAltStyleOnNull", typeof (bool), typeof (ExtendedTextBlock), new PropertyMetadata(default(bool)));

    public bool AllowAltStyleOnNull {
        get { return (bool) GetValue(AllowAltStyleOnNullProperty); }
        set { SetValue(AllowAltStyleOnNullProperty, value); }
    }

    public static readonly DependencyProperty AltStyleProperty =
        DependencyProperty.Register("AltStyle", typeof (Style), typeof (ExtendedTextBlock), new PropertyMetadata(default(Style)));

    public Style AltStyle {
        get { return (Style) GetValue(AltStyleProperty); }
        set { SetValue(AltStyleProperty, value); }
    }

    static ExtendedTextBlock() {
        TextProperty.OverrideMetadata(typeof(ExtendedTextBlock), new FrameworkPropertyMetadata(default(string), PropertyChangedCallback));
    }

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) {
        var tb = (ExtendedTextBlock)dependencyObject;
        var binding = tb.GetBindingExpression(TextProperty);
        if (binding != null && binding.DataItem == null) {
            if (tb.AllowAltStyleOnNull)
                tb.Style = tb.AltStyle;
        }
    }
}

Вам нужно будет немного конкретизировать это, чтобы быть готовым к производству, но вы поняли идею.

...