Коллекции обновлений WPF MVVM для обновления пользовательского интерфейса - PullRequest
0 голосов
/ 15 ноября 2010

Я хочу обновить свой интерфейс.Должен ли я использовать BackgroundWorker?Должен ли я поместить BackgroundWorker в MainWindowViewModel и снова создать экземпляры репозиториев, или я должен поместить его в OrdersQueueViewModel и что-то сделать со свойствами?

Пользовательский интерфейс просто отображает содержимое списков, созданных LINQ.Списки ObservableCollection и являются свойствами OrdersQueueViewModel.У меня есть ViewModel MainWindowViewModel, которая создает коллекцию ViewModel, так что я могу привязать к этой коллекции из MainWindow.xaml (view).

MainWindowViewModel.cs:

public MainWindowViewModel()
{
    _printQueueRepos = new OrdersPrintQueueRepository();
    _holdQueueRepos = new OrdersHoldQueueRepository();            
    _linesToPickRepos = new LinesToPickRepository();
    _linesPerHourRepos = new LinesPerHourRepository();

    //create an instance of viewmodel and add it to the collection            
    OrdersQueueViewModel viewModel = new OrdersQueueViewModel(_printQueueRepos, _holdQueueRepos, _linesToPickRepos, _linesPerHourRepos);
    this.ViewModels.Add(viewModel);              
}

MainWindow.xaml:

<Window.Resources>
    <DataTemplate DataType="{x:Type vm:OrdersQueueViewModel}">
        <vw:OrdersQueueView></vw:OrdersQueueView>
    </DataTemplate>
</Window.Resources>

Пример свойства в OrderQueueViewModel, использующего репозиторий:

public ObservableCollection<LinesToPick> LinesToPick
{
    get
    {
        return new ObservableCollection<LinesToPick>(_linesToPickRepos.GetLinesToPick());
    }
}

Так что у меня есть LinesToPick, связанный в OrdersQueueView, и по мере обновления базы данных списки должныизменить в интерфейсе.Я потратил некоторое время, читая о BackgroundWorker, но я не совсем уверен, что делать, чтобы обновить списки.Я надеюсь, что они ObservableCollections. Я могу просто «обновить» их, и они будут использовать INotifyPropertyChanged и обновлять пользовательский интерфейс автоматически.Очень новичок во всем этом, пытаясь разобраться в этом, заранее благодарю за любую помощь.

РЕДАКТИРОВАТЬ: Используя предложение Джеймса, я закончил с этим в моем OrdersQueueViewModel.Однако я получаю сообщение об ошибке " Этот тип CollectionView не поддерживает изменения в его SourceCollection из потока, отличного от потока Dispatcher ", когда код попадает в .Clear () в 2 списках, чточто я думал, что диспетчер был использован для.Есть предложения?

Action workAction = delegate
{
    _worker = new BackgroundWorker();
    _worker.DoWork += delegate
    {
        LinesThroughput.Clear();
        LinesToPick.Clear();

        //refresh LinesToPick
        foreach (var item in _linesToPickRepos.GetLinesToPick())
        {
            LinesToPick.Add(item);
        }

       //refresh LinesThroughput
       List<LinesThroughput> Lines = new List<LinesThroughput>    (_linesPerHourRepos.GetLinesThroughput());

       foreach (var item in GetLinesThroughput(Lines))
       {
           LinesThroughput.Add(item);
       }
   };
   _worker.RunWorkerAsync();
};
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Normal, workAction);

1 Ответ

0 голосов
/ 15 ноября 2010

Вы можете сделать это любым способом - в MainWindowViewModel или в одной из моделей дочерних представлений.Я бы выбрал, основываясь на том, какой путь обеспечивает более низкую связь и более высокую когезию между компонентами.(Более низкая связь - меньше зависимостей. Более высокая сплоченность - вещи идут вместе, которые логически связаны друг с другом.)

И BackgroundWorker - разумный метод.Просто не забудьте отправить в поток пользовательского интерфейса, чтобы обновить коллекцию.Что касается вашего кода ObservableCollection ... Это требует некоторой работы.Не восстанавливайте ObservableCollection.Сделайте что-то вроде этого:

public ObservableCollection<LinesToPick> LinesToPick { get; private set; }  // Don't forget to nstantiate in ctor

public void Refresh()
{
    LinesToPick.Clear();
    foreach(var item in _linesToPickRepos.GetLinesToPick())
    {
        LinesToPick.Add(item);
    }
}

Сохраняя ту же коллекцию ObservableCollection, которая была привязана к данным, ваш пользовательский интерфейс будет автоматически принимать изменения в коллекции.Если вы замените коллекцию, вы потеряете привязку к ней, и ваш пользовательский интерфейс не будет обновляться, пока вы не уведомите ее об изменении свойства, содержащего коллекцию.Гораздо проще просто хранить одну и ту же коллекцию.

...