为什么此ListView不会随着绑定属性的更改而改变?

时间:2017-07-29 21:06:58

标签: c# wpf listview mvvm

新手的基本问题。我一直坚持这一点,并在SO上阅读了很多材料和几个类似的问题;希望不是一个完全重复的问题。我尽可能地简化了代码。

我试图让ListView显示一个过滤的ObservableCollection属性(作为ItemsSource?),基于ComboBox中的选择。  具体来说,会议"会议"有这个"协调员"与之相关。

我在输出运行时没有看到任何数据错误,并且调试显示属性正确更新,但ListView保持空白。我试图避免View上的任何代码隐藏,目前没有。

谢谢!

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>

更新

这似乎表明lambda正在返回一个Meeting对象,但是对Meetings的分配失败了。这可能是投射错误吗?

再次感谢。

2 个答案:

答案 0 :(得分:3)

在触发PropertyChanged事件之前,您始终必须更改属性的支持字段。否则,事件的使用者在读取属性时仍会获得旧值。

更改会议属性设置器,如下所示:

public ObservableCollection<Meeting> Meetings
{
    get
    {
        return meetings;
    }
    set
    {
        meetings = value;
        OnPropertyChanged("ListProperty");
        OnPropertyChanged("Meetings");
    }
}

答案 1 :(得分:1)

我相信我找到了两个同样问题的解决方案。错误指出@Clemens也是解决方案的一部分。如果我将ListProperty和Meetings更改为IEnumerable,则会解决Meetings属性问题。或者这种方法不改变类型,我相信它会调用集合的构造函数,并将过滤后的序列作为参数。

set
{
    coordinatorSelected = value;
    var filteredList = fakeDB.Where(v => v.CoordinatorName == coordinatorSelected);
    Meetings = new ObservableCollection<Meeting>(filteredList);
    OnPropertyChanged("ListProperty");
}