【问题标题】:Why is this ListView not changing with changes to the bound property?为什么这个 ListView 不会随着绑定属性的变化而变化?
【发布时间】:2017-07-29 21:06:58
【问题描述】:

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

我正在尝试根据 ComboBox 中的选择使 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>

更新:

这似乎表明 lambda 正在返回一个会议对象,但对会议的分配失败。这可能是铸造错误吗?

再次感谢。

【问题讨论】:

  • 这里不需要该选项,仅使用源代码 - ItemsSource="{Binding ListProperty, UpdateSourceTrigger=PropertyChanged}"
  • 请注意,UpdateSourceTrigger=PropertyChanged 对单向绑定没有影响。它控制 TwoWay 或 OneWayToSource 绑定如何更新其源属性。

标签: c# wpf listview mvvm


【解决方案1】:

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

像这样更改会议属性设置器:

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

【讨论】:

  • 感谢您的宝贵时间。很好的收获,我已经纠正了这个错误。我认为在设置器中分配给会议的问题 - 我将更新问题以修复代码并包含调试器的屏幕截图。我认为这可能是一个选角问题,但对我来说是正确的。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2021-08-22
    • 2018-05-19
    • 2017-06-22
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-22
    相关资源
    最近更新 更多