Общий стиль для текстовых полей с привязкой текста в wpf с использованием триггеров

У меня есть требование, в котором TextBox привязан к свойству с ViewModel. Значение по умолчанию равно -1, но я хочу показывать пользователю не -1, а "по умолчанию". У меня есть подобные текстовые поля во многих местах моего проекта. Итак, стиль был создан и задано свойство Text в DataTrigger, но почему-то код не работал. Я все еще изучаю Wpf.

Пожалуйста помоги.

XAML выглядит следующим образом.

<Window x:Class="TextBoxDefaultStyles.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TextBoxDefaultStyles"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>

    <Style TargetType="TextBox"
           x:Key="DefaultStyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}}" Value="-1">
                <Setter Property="Text" Value="Default"/>
                <Setter Property="Foreground" Value="Gray"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<StackPanel>
    <TextBox Text="{Binding Text}"
             Style="{StaticResource DefaultStyle}"/>
    <TextBox Text="Dummy"/>
</StackPanel>

I want to have the behavior, if the Binding value is -1, then show Default as text or if Binding value is <> -1 then show that text. If a user enters text in the editbox, usually numbers then that has to be updated to the underlying binding.


person Rahul W    schedule 13.08.2014    source источник
comment
Является ли свойство, которое вы привязываете к строке или другому типу?   -  person Lee O.    schedule 13.08.2014
comment
Вам нужно будет удалить RelativeSource из привязки в DataTrigger. Тем не менее, это только установит свойство Foreground, но не заменит Text. Вместо этого просто используйте конвертер привязки.   -  person Clemens    schedule 13.08.2014
comment
Это просто работа для FallbackValue в базе привязок?   -  person Chris W.    schedule 13.08.2014
comment
@ЛиО. Привязка к целочисленному типу свойства.   -  person Rahul W    schedule 13.08.2014


Ответы (2)


То, что вы пытаетесь сделать, не сработает из-за Приоритет значений свойств зависимостей, используемый в WPF. DependencyPropertys можно установить из нескольких разных источников, поэтому Microsoft пришлось разработать список приоритетов значений... какой источник должен иметь больший приоритет?

Если вы посмотрите на связанную страницу, вы увидите список приоритетов свойств зависимостей, в котором показано, какие источники имеют приоритет над другими. То, что вы пытаетесь сделать, это перезаписать значение, установленное привязкой данных (Local Value в списке), значением, установленным Style Trigger. Обратите внимание, что запись Style Triggers находится намного ниже в списке, чем запись Local Value.

Это означает, что он имеет меньший приоритет, чем запись Local Value, и поэтому он никогда не перезапишет это значение.

Вместо этого чаще используется IValueConverter Интерфейс для преобразования значения -1 в Default.

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (string.IsNullOrEmpty(value)) return DependencyProperty.UnsetValue;
    return value.ToString() == "-1" ? "Default" : value;
}
person Sheridan    schedule 13.08.2014
comment
+1 для приоритета значения свойства зависимостей. Спасибо - person Rahul W; 13.08.2014

это не работает, потому что Local Value имеет более высокий приоритет, чем Trigger Value . Приоритет свойств зависимостей

Попробуйте использовать конвертер

xaml

<Window x:Class="Stackoverflow.Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window2" Height="300" Width="300"
    xmlns:local="clr-namespace:Stackoverflow"
    >
<Window.Resources>
    <local:TextConverter x:Key="textConverter"/>
</Window.Resources>

<Grid>
    <TextBox Text="{Binding Name, Converter=textConverter}"/>
</Grid>

Converter

    public class TextConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value.ToString() == "-1")
            return "Default";
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
person yo chauhan    schedule 13.08.2014
comment
а как насчет свойства Foreground? Нужно ли мне использовать другой преобразователь для проверки того, является ли текст значением по умолчанию или фактическим значением. - person Rahul W; 13.08.2014
comment
Используйте триггер для свойства Foreground, как в вашем собственном примере. Вместо того, чтобы проверять, является ли текст -1, проверьте, является ли он значением по умолчанию. - person Lee O.; 13.08.2014
comment
да, для переднего плана используйте триггер, но в триггере установите значение = по умолчанию вместо -1. - person yo chauhan; 13.08.2014