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}}
我正在尝试根据内容更改 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}}