【发布时间】:2020-08-15 01:47:59
【问题描述】:
我正在尝试将 XAML 中 WPF UI 元素的可见性绑定到我的视图模型 (MainViewModel.DisplayPopup) 的属性,该属性是从另一个视图模型 (ContactViewModel) 的属性更新的,它是一个属性此类(MainViewModel)。 BaseViewModel 类扩展了 INotifyPropertyChanged 并使用了一个 Nuget 包,该包在每个属性的设置器中自动调用 PropertyChanged 事件。
这是我的视图模型代码:
public class MainViewModel : BaseViewModel
{
public ObservableCollection<ContactViewModel> TankItems {get; set; }
public bool DisplayPopup
{
get => TankItems.Any(contact => contact.DisplayPopup);
}
public MainViewModel() : base()
{
TankItems = new ObservableCollection<ContactViewModel>();
TankItems.Add(new ContactViewModel());
TankItems.Add(new ContactViewModel());
}
}
public class ContactViewModel : BaseViewModel
{
private bool _isSelected = false;
public bool DisplayPopup {get; set; } = false;
public bool IsSelected {get => _isSelected; set { _isSelected = value; DisplayPopup = value;
}
这是我的 XAML:
<ListBox Grid.Column="0" ItemsSource="{Binding TankItems}" SelectionChanged="List_SelectionChanged">
<ListBox.Style>
<Style TargetType="ListBox">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.Style>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="Test" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border BorderBrush="Orange" BorderThickness="3" Grid.Column="1">
<TextBlock Text="{Binding DisplayPopup}" /> <!-- Stays as false -->
</Border>
我期望发生的是,当我单击 ListBox 项目之一时,DisplayPopup 变为 true,但它保持不变。但是,如果我记录 ((MainViewModel)DataContext).DisplayPopup) 的值,我会得到正确的值 - 开头是 false,然后在更改选择时是 true。
为什么绑定值没有更新?
更新
这里是BaseViewModel,它使用Fody PropertyChanged
[AddINotifyPropertyChangedInterfaceAttribute]
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
【问题讨论】:
-
你能提供更多关于BaseViewModel的信息吗? INotifyPropertyChanged 接口在哪里实现?你在使用 Fody PropertyChanged 吗?
-
您可以删除 AddINotifyPropertyChangedInterfaceAttribute,因为您为您的班级使用了 INotifyPropretyChanged。 Fody Property Changed 注入了每个实现 INotifyPropertyChanged 的类。你试过手动抬高吗?
-
在 DisplayPopup 中,您指定了一个表达式来计算一个值。该值取决于 TankItems 集合中项目的值,并且计算正确。您希望绑定到此属性也会更改该值。但这种期望是不正确的。为此,请创建一个 PropertyChanged (DisplayPopup),以防任何 TankItems 发生变化。你的代码没有这样做。如何使用 FodyPropertyChanged 做到这一点 - 我不知道。我没有使用这个包。
-
要拼出 EldHasp 在他的评论中所说的内容(让它成为答案!),您有“一个 Nuget 包,它会自动在每个属性的设置器中调用 PropertyChanged 事件”,但
MainViewModel.DisplayPopup没有'没有二传手。
标签: c# .net wpf mvvm synchronization