WPF DataTrigger 为 false 但不会恢复为以前的值
WPF DataTrigger is false but doesn't revert to previous value
我最近创建了一个用户控件,用于通知用户他有多少条通知。因为我希望这个用户控件仅在有任何通知时显示自己,所以我创建了一个绑定到 bool 的 DataTrigger 并在没有通知时将可见性设置为折叠。一开始它工作正常,我的用户控件折叠了,但在我的程序中我添加了一个通知并在我的 bool 上调用 NotifyPropertyChanged 但用户控件由于某些未知原因仍然保持隐藏状态。
用户控制
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Visibility"
Value="Visible">
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HasNotifications}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
数据上下文
private ObservableCollection<Notification> notifications;
public ObservableCollection<Notification> Notifications
{
get { return notifications; }
}
public bool HasNotifications
{
get
{
return Notifications.Count > 0;
}
}
public void AddNotification(Notification notificationToAdd)
{
notifications.Add(notificationToAdd);
NotifyPropertyChanged(nameof(Notifications));
NotifyPropertyChanged(nameof(HasNotifications));
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
我也尝试过设置一个具有相反值的 DataTrigger(当 HasNotifications 为真时将可见性设置为 on),但它对我来说也没有用。
我复制了你的代码,在3.5和4.7框架下测试过,可以用。我只能在一种情况下重现您的问题,但我在这里猜测是因为该部分不在您的代码示例中。
仅当数据上下文 class 不继承自 INotifyPropertyChanged
时才有效。否则,最小代码示例将按预期工作。
public class MyDataContext : INotifyPropertyChanged // <= doesn't work if this is missing
{
private ObservableCollection<Notification> notifications = new ObservableCollection<Notification>();
public ObservableCollection<Notification> Notifications => notifications;
public bool HasNotifications=> Notifications.Count > 0;
public void AddNotification(Notification notificationToAdd)
{
notifications.Add(notificationToAdd);
NotifyPropertyChanged(nameof(Notifications));
NotifyPropertyChanged(nameof(HasNotifications));
}
private ICommand _AddNotification;
public ICommand AddNotificationCMD => _AddNotification ?? (_AddNotification = new RelayCommand<object>(a => AddNotificationCommand(a)));
private void AddNotificationCommand(object item)
{
AddNotification(new Notification());
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="WpfApp_3_5_framework_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp_3_5_framework_test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:UserControl1/>
<Button Content="Add Notification" Command="{Binding AddNotificationCMD}" Height="20" Width="200" />
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyDataContext();
}
}
<UserControl x:Class="WpfApp_3_5_framework_test.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp_3_5_framework_test"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Visibility"
Value="Visible">
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HasNotifications}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<Grid>
<StackPanel>
<Border Width="100" Height="100" Background="Red"/>
</StackPanel>
</Grid>
</UserControl>
我最近创建了一个用户控件,用于通知用户他有多少条通知。因为我希望这个用户控件仅在有任何通知时显示自己,所以我创建了一个绑定到 bool 的 DataTrigger 并在没有通知时将可见性设置为折叠。一开始它工作正常,我的用户控件折叠了,但在我的程序中我添加了一个通知并在我的 bool 上调用 NotifyPropertyChanged 但用户控件由于某些未知原因仍然保持隐藏状态。
用户控制
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Visibility"
Value="Visible">
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HasNotifications}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
数据上下文
private ObservableCollection<Notification> notifications;
public ObservableCollection<Notification> Notifications
{
get { return notifications; }
}
public bool HasNotifications
{
get
{
return Notifications.Count > 0;
}
}
public void AddNotification(Notification notificationToAdd)
{
notifications.Add(notificationToAdd);
NotifyPropertyChanged(nameof(Notifications));
NotifyPropertyChanged(nameof(HasNotifications));
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
我也尝试过设置一个具有相反值的 DataTrigger(当 HasNotifications 为真时将可见性设置为 on),但它对我来说也没有用。
我复制了你的代码,在3.5和4.7框架下测试过,可以用。我只能在一种情况下重现您的问题,但我在这里猜测是因为该部分不在您的代码示例中。
仅当数据上下文 class 不继承自 INotifyPropertyChanged
时才有效。否则,最小代码示例将按预期工作。
public class MyDataContext : INotifyPropertyChanged // <= doesn't work if this is missing
{
private ObservableCollection<Notification> notifications = new ObservableCollection<Notification>();
public ObservableCollection<Notification> Notifications => notifications;
public bool HasNotifications=> Notifications.Count > 0;
public void AddNotification(Notification notificationToAdd)
{
notifications.Add(notificationToAdd);
NotifyPropertyChanged(nameof(Notifications));
NotifyPropertyChanged(nameof(HasNotifications));
}
private ICommand _AddNotification;
public ICommand AddNotificationCMD => _AddNotification ?? (_AddNotification = new RelayCommand<object>(a => AddNotificationCommand(a)));
private void AddNotificationCommand(object item)
{
AddNotification(new Notification());
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="WpfApp_3_5_framework_test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp_3_5_framework_test"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:UserControl1/>
<Button Content="Add Notification" Command="{Binding AddNotificationCMD}" Height="20" Width="200" />
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MyDataContext();
}
}
<UserControl x:Class="WpfApp_3_5_framework_test.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp_3_5_framework_test"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Style>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Visibility"
Value="Visible">
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding HasNotifications}"
Value="False">
<Setter Property="Visibility"
Value="Collapsed">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
<Grid>
<StackPanel>
<Border Width="100" Height="100" Background="Red"/>
</StackPanel>
</Grid>
</UserControl>