为什么这个ListView不会随着绑定属性的改变而改变?
来自新手的基本问题。我一直在坚持这一点,并已阅读了很多关于SO的材料和几个类似的问题;希望不是完全重复的问题。尽我所知,我简化了代码。为什么这个ListView不会随着绑定属性的改变而改变?
我想使ListView显示一个过滤的ObservableCollection)属性(作为ItemsSource?),基于组合框中的选择。 具体而言,哪些“会议”具有与此相关的“协调员”。
我在运行时看不到任何输出数据错误,调试显示属性正确更新,但ListView保持空白。我试图避免视图上的任何代码隐藏,目前没有任何代码隐藏。
谢谢!
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<Meeting> meetings;
public ObservableCollection<Meeting> Meetings
{
get
{
return meetings;
}
set
{
meetings = value;
OnPropertyChanged("ListProperty");
OnPropertyChanged("Meetings");
}
}
private string coordinatorSelected;
public string CoordinatorSelected
{
get
{
return coordinatorSelected;
}
set
{
coordinatorSelected = value;
Meetings = fakeDB.Where(v => v.CoordinatorName == CoordinatorSelected) as ObservableCollection<Meeting>;
}
}
private ObservableCollection<string> comboProperty = new ObservableCollection<string> { "Joe", "Helen", "Sven" };
public ObservableCollection<string> ComboProperty
{
get
{
return comboProperty;
}
}
private ObservableCollection<Meeting> fakeDB = new ObservableCollection<Meeting>() { new Meeting("Joe", "Atlas"), new Meeting("Sven", "Contoso"), new Meeting("Helen", "Acme") };
public ObservableCollection<Meeting> ListProperty
{
get
{
return Meetings;
}
}
public class Meeting
{
public string CoordinatorName { get; set; }
public string ClientName { get; set; }
public Meeting(string coordinatorName, string clientName)
{
CoordinatorName = coordinatorName;
ClientName = clientName;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML:
<Window.Resources>
<local:ViewModel x:Key="VM"></local:ViewModel>
</Window.Resources>
<DockPanel DataContext="{StaticResource ResourceKey=VM}">
<ComboBox Margin="10" ItemsSource="{Binding ComboProperty}" SelectedItem="{Binding CoordinatorSelected}" DockPanel.Dock="Top"/>
<ListView Margin="10" ItemsSource="{Binding ListProperty, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ClientName"/>
</DockPanel>
更新:
这似乎表明,拉姆达返回一个会议对象,但分配给会议失败。这可能是铸造中的错误吗?
再次感谢。
我相信我已经发现了两个解决方案,以同样的问题。错误指出@Clemens也是解决方案的一部分。如果我将ListProperty和Meetings更改为IEnumerable,会议属性问题即告解决。或者,这种方法不改变类型,我相信它将过滤的序列作为参数调用集合的构造函数。
set
{
coordinatorSelected = value;
var filteredList = fakeDB.Where(v => v.CoordinatorName == coordinatorSelected);
Meetings = new ObservableCollection<Meeting>(filteredList);
OnPropertyChanged("ListProperty");
}
在触发PropertyChanged事件之前,您总是必须更改属性的后台字段。否则,该事件的消费者在读取该财产时仍会获得旧值。
更改会议属性的setter方法是这样的:
public ObservableCollection<Meeting> Meetings
{
get
{
return meetings;
}
set
{
meetings = value;
OnPropertyChanged("ListProperty");
OnPropertyChanged("Meetings");
}
}
谢谢你的时间。很好,我纠正了这个错误。我认为在setter中分配给Meetings会有问题 - 我将更新问题以修复代码并包含调试器的屏幕截图。我认为这可能是一个铸造问题,但它看起来是对的。 – gnivler
选项这里不需要,只使用源工程 - '的ItemsSource = “{结合的ListProperty,UpdateSourceTrigger =的PropertyChanged}”' – gnivler
注意,'UpdateSourceTrigger = PropertyChanged'对单向绑定没有影响。它控制TwoWay或OneWayToSource绑定如何更新其源属性。 – Clemens