WPF ListView не обновляется

#c# #wpf

#c# #wpf

Вопрос:

У меня есть представление списка и привязка ItemSource к общедоступному списку ObservableCollection { get; set; } . Я инициировал StoclList в методе конструктора. Я получаю отфильтрованный список запасов из ViewModel и добавляю эти элементы в этот StcokList, но почему-то ListView не показывает элементы списка.

Но если я установлю ItemsSource=»{Привязка ListFromViewModel}», это сработает..

  public partial class MainWindow : Window     {   

    public MainWindowViewModel viewModel;
    public ObservableCollection<StockModel> StockList { get; set; }

    //Constructor
    public MainWindow()
    {
        StockList = new ObservableCollection<StockModel>();
        InitializeComponent();
        viewModel = new MainWindowViewModel();
        this.DataContext = viewModel;           
    }

    private async void BtnSelectFile_Click(object sender, RoutedEventArgs e)
    {
        GetData();
        viewModel.StartProcessing(progress);
        StockList.Clear();
        for (int i = 0; i < viewModel.ListOfStocks.Count; i  )
        {
            StockList.Add(viewModel.ListOfStocks[i]);
        }
    }
  

И мой файл XAML выглядит следующим образом

 <ListView Grid.Row="1" Grid.Column="1" x:Name="LvErrorList" ItemsSource="{Binding StockList}">
  

ОБНОВЛЕНИЕ: если я использую этот код, он начнет работать. Но я не уверен, почему!!!

 LvErrorList.ItemsSource = StockList;
  

Комментарии:

1. StockList является свойством класса MainWindow, в то время как вы устанавливаете DataContext в экземпляр MainWindowViewModel . Как это должно работать? Вы намеревались иметь свойство StockList в MainWindowViewModel? Какова цель модели представления в противном случае?

2. Спасибо за ваш ответ, Клеменс. Так потому, что я установил это. DataContext = ViewModel; Мой MainWindow.xaml будет игнорировать все мои привязки MainWindow? Привязки работают только в том случае, если я объявляю их внутри ViewModeClass?

3. Если вы явно не задали исходный объект привязки, он использует текущий DataContext. Не уверен, имеет ли это смысл, но вы могли бы написать ItemsSource="{Binding StockList, RelativeSource={RelativeSource AncestorType=Window}}" . Но свойство, конечно, должно быть в классе модели представления, если он у вас уже есть.

Ответ №1:

Когда вы вводите {Binding StockList} свою разметку XAML, WPF попытается привязаться к StockList свойству текущего DataContext из ListView .

Поскольку ListView наследует его DataContext от родительского элемента вплоть до родительского окна, он будет искать свойство в MainWindowViewModel объекте, которое вы установили как DataContext в конструкторе окна.

Если вы установите DataContext экземпляр класса, в котором StockList определено свойство, то есть само окно в данном случае, ваша привязка будет работать:

 this.DataContext = this;
  

В качестве альтернативы вы можете переместить StockList свойство в модель представления или отказаться DataContext от нее, указав явный источник для привязки. Это будет привязано к StockList свойству самого окна независимо от DataContext :

 <ListView Grid.Row="1" Grid.Column="1" x:Name="LvErrorList"
    ItemsSource="{Binding StockList, RelativeSource={RelativeSource AncestorType=Window}}">
  

Пожалуйста, обратитесь к документации для получения дополнительной информации о привязке данных в WPF и о том, как это работает.

Комментарии:

1. Спасибо за помощь