为什么 UI 没有反映我的 ObservableCollection 中的更改?

问题描述 投票:0回答:1

我有三个列表视图,第一个显示通用列表,当双击某个元素时,以下两个列表视图应该“分支”出来。例如,第一个列表显示汽车、卡车、自行车。双击“汽车”时,下一个列表视图应显示 SUV、轿车、小型货车等。单击其中一个时,在本例中假设为 SUV,最后一个列表应显示 2023 斯巴鲁森林人、2023 福特探险家等。三个主要可观察对象集合在页面加载时填充,如下所示的引用,因为它们最终必须被过滤。我有所有三个和可观察集合的模型,声明如下:

private ObservableCollection<VehicleGeneral> _vehiclegenerals;
        public ObservableCollection<VehicleGeneral> VehicleGenerals
        {
            get { return _vehiclegenerals; }
            set
            {
                _vehiclegenerals= value;
                OnPropertyChanged(nameof(VehicleGenerals));
            }
        }

上面的集合是所有三个集合的准确定义方式。

这是 Xaml 绑定: 请注意,所有三个列表视图的定义完全如下,当然只是名称和绑定不同。

<ListView
                Grid.Row="1"
                Grid.ColumnSpan="3" 
                ItemsSource="{Binding VehicleGenerals,Mode=TwoWay}"
                SelectedItem="{Binding VehicleIndex, Mode=TwoWay}"
                MouseDoubleClick="ListView_MouseDoubleClickVehicle"
                x:Name="VehicleList"

使用 ItemSource:

private VehicleGeneral _vehicleIndex;
        public VehicleGeneral VehicleIndex
        {
            get { return _vehicleIndex; }
            set
            {
                if (value != null)
                {
                    _vehicleIndex= value;
                    OnPropertyChanged(nameof(VehicleIndex));
                    SetObjectText(VehicleIndex, null, null); //This can be ignored I'm just setting label text
                }
            }
        }

我确信有一种更简洁的方法可以将值重新分配给可观察的集合,我觉得我已经尝试了所有这些方法,但这就是我现在在代码中更新它的方法。

//Code Behind
private void ListView_MouseDoubleClickVehicle(object sender, MouseButtonEventArgs e)
        {
            _viewModel.ListDoubleClicked(VehicleList.SelectedIndex);
        }

...
//In Viewmodel
 public void ListDoubleClicked(int? index)
        {
            
            if (index != null )
            {
                var vehicle = VehicleGeneralHolder[(int)index];
                var filtered = VehicleTypeHolder.Where(x => (int)x.VehicleGeneralId == vehicle.Id).ToList();
                _vehicleType.Clear();
                //_vehicleType = new ObservableCollection<VehicleType>(filtered);
                foreach (var item in filtered)
                {
                    _vehicleType .Add(item);
                }
            }
        }

如果需要更多细节,我会很乐意提供,总的来说,我完全不知道为什么这不能按预期工作。

我的主视图模型(其中显示的代码继承的视图模型)具有 INotifyPropertyChanged。我尝试过明确声明绑定为 OneWay 或 TwoWay。以各种不同的方式添加/删除 ObservableCollection 元素。代码有效并且元素被过滤,但由于某种原因,UI 没有反映这些更改。

c# wpf xaml listview
1个回答
0
投票

如果您要使用如下代码:

_vehicleType = new ObservableCollection<VehicleType>(filtered); // Use VehicleType = ... to ensure OnPropertyChanged raised.

(已被注释掉,但您似乎已经尝试过)您可能希望通过属性访问器而不是私有成员来使用它,以确保在侦听 VehicleType 项源的任何内容上引发

OnPropertyChanged

至于修改可观察集合本身,代码如下:

_vehicleType.Clear();
foreach (var item in filtered)
{
    _vehicleType .Add(item);
}

...应该可以工作,只要 _vehicleType 是

ObservableCollection<VehicleType>
。一个可能的问题是在 ItemSource 引用上使用双向绑定。 WPF 将根据预期的消费者绑定需求默认绑定,您只需在偏离该方向时显式指定绑定方向。您可以尝试将下拉菜单上的绑定调整为默认值:

ItemsSource="{Binding Path=VehicleGenerals}" // Should default to 1-way
SelectedItem="{Binding Path=VehicleIndex}" // Should default to 2-way
© www.soinside.com 2019 - 2024. All rights reserved.