使用触发器在wpf中使用文本绑定的文本框的通用样式

时间:2014-08-13 15:57:54

标签: c# wpf xaml binding datatrigger

我要求TextBox绑定到ViewModel的属性。默认值为-1,但我不希望将-1显示为用户,而是显示为“默认”。我的项目中有很多类似的文本框。因此,创建了一个样式并在DataTrigger中设置Text属性,但不知何故代码无效。 我还在学习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>

我希望有行为,如果Binding值为-1,则将Default显示为文本或者Binding值是&lt;&gt; -1然后显示该文本。如果用户在编辑框中输入文本,通常需要将数字更新为基础绑定。

2 个答案:

答案 0 :(得分:1)

由于WPF中使用的Dependency Property Value Precedence列表,您尝试执行的操作无效。 DependencyProperty可以从几个不同的来源设置,因此Microsoft必须设计一个值优先级列表...哪个源应该有更多的优先级?

如果查看链接页面,您将看到“依赖项属性设置优先级列表”,该列表显示哪些源优先于其他源。您要做的是覆盖由数据绑定(列表中的 Local Value )设置的值,其值由Style Trigger设置。您应该注意到 Style Triggers 条目在列表中比 Local Value 条目低得多。

这意味着它的少于优先级 Local Value 条目,因此它永远不会覆盖该值。

相反,更常见的是使用IValueConverter Interface-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;
}

答案 1 :(得分:0)

这不起作用,因为Local Value的优先级高于Trigger Value。 Dependency Property Precedence

使用Converter

尝试
  

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>

  

转换器

    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();
    }
}