WPF 数据触发器未触发

WPF datatrigger not firing

我正在尝试根据内容更改 WPF 文本框的背景颜色。

使用断点,我看到我的 ValueConverter 已构建,但 Convert 和 ConvertBack 方法都未被调用,因此样式不起作用。

XAML 中的 'LightBlue' 样式在启动时确实有效。

我尝试使用 Snoop,但我不知道我在寻找什么。

XAML...

    <Grid.Resources>
        <local:ThreadCreationLimitChanged x:Key="ThreadCreationLimitChanged"></local:ThreadCreationLimitChanged>
    </Grid.Resources>
    <Label Grid.Row="0" Grid.Column="0" Margin="0, 5, 0, 0" Content="New Thread Limit"></Label>
    <TextBox Grid.Row="0" Grid.Column="1" Margin="10, 5, 10, 0" Width="100" Text="{Binding Path=ManagerConfig.ThreadCreationLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
        <TextBox.Style>
            <Style>
                <Setter Property="TextBox.Background" Value="LightBlue"></Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=Text,Converter={StaticResource ThreadCreationLimitChanged}}" Value="false">
                        <Setter Property="TextBox.Background" Value="Yellow"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>

值转换器...

public class ThreadCreationLimitChanged : IValueConverter
{
    public ThreadCreationLimitChanged()
    {
    }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.ToString() == "120";
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

一些 class ManagerConfig...(NotifyPropertyChanged 实现 INotifyPropertyChanged)

class ManagerConfig : NotifyPropertyChanged
{
    private uint _ThreadCreationLimit;

    public uint ThreadCreationLimit
    {
        get { return _ThreadCreationLimit; }
        set
        {
            _ThreadCreationLimit = value;
            OnPropertyChanged("ThreadCreationLimit");
        }
    }

为什么不在 ManagerConfig 上创建一个计算 属性 来报告 ThreadCreationLimit 的更改状态?这样就不需要转换器了。代码如下:

public bool IsOverLimit { get { return ThreadCreationLimit > 120 } }

 public uint ThreadCreationLimit
    {
        get { return _ThreadCreationLimit; }
        set
        {
            _ThreadCreationLimit = value;
            OnPropertyChanged("ThreadCreationLimit");
            OnPropertyChanged("IsOverLimit");
        }
    }

然后将数据触发器绑定到 IsOverLimit,每次 ThreadCreationLimit 为 set/changed 时都会发送更改通知。

一个额外的优点是业务逻辑在预期的 class 而不是转换器上。

我猜你正在像下面那样检查 Binding errors.Have,

1) 为Value直接访问TextBox,

<Grid.Resources>
    <local:ThreadCreationLimitChanged x:Key="ThreadCreationLimitChanged"></local:ThreadCreationLimitChanged>
</Grid.Resources>
<Label Grid.Row="0" Grid.Column="0" Margin="0, 5, 0, 0" Content="New Thread Limit"></Label>
<TextBox x:Name="tBox" Grid.Row="0" Grid.Column="1" Margin="10, 5, 10, 0" Width="100" Text="{Binding Path=ManagerConfig.ThreadCreationLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    <TextBox.Style>
        <Style>
            <Setter Property="TextBox.Background" Value="LightBlue"></Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Text, ElementName=tBox,Converter={StaticResource ThreadCreationLimitChanged}}" Value="false">
                    <Setter Property="TextBox.Background" Value="Yellow"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

2) 访问正确的模型值,

 <Grid.Resources>
    <local:ThreadCreationLimitChanged x:Key="ThreadCreationLimitChanged"></local:ThreadCreationLimitChanged>
</Grid.Resources>
<Label Grid.Row="0" Grid.Column="0" Margin="0, 5, 0, 0" Content="New Thread Limit"></Label>
<TextBox Grid.Row="0" Grid.Column="1" Margin="10, 5, 10, 0" Width="100" Text="{Binding Path=ManagerConfig.ThreadCreationLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
    <TextBox.Style>
        <Style>
            <Setter Property="TextBox.Background" Value="LightBlue"></Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=ManagerConfig.ThreadCreationLimit,Converter={StaticResource ThreadCreationLimitChanged}}" Value="false">
                    <Setter Property="TextBox.Background" Value="Yellow"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

将此 {Binding Path=Text,Converter={StaticResource ThreadCreationLimitChanged}} 更改为 {Binding Path=Text, RelativeSource={RelativeSource Self} ,Converter={StaticResource ThreadCreationLimitChanged}}