Silverlight - MVVM: сетка данных, привязанная к ICollectionView, заполненная "ChildViewModel", не будет обновлять данные

Я не смог найти похожий случай, и я продолжаю бороться. Я довольно приверженец Silverlight и борюсь с обновлением ICollectionView. Метод Refresh на самом деле не будет обновлять данные в моей сетке данных, хотя они изменены (посмотрите это в отладчике, и после сортировки сетки данных несколько раз, наконец, будут отражены изменения). Боюсь, я полностью испортил всю конструкцию своего приложения. Я думаю, что проблема как-то связана с моим принципом "MainViewModel-ChildViewModel", который я реализовал.

Вот моя конструкция: На моей главной странице я добавил "Основную модель представления" в качестве ресурса.

<UserControl.Resources>
        <vm:WorkingBasketViewModel x:Key="VMMain"/>
</UserControl.Resources>

Grid LayoutRoot затем устанавливает его текстовый текст для этой модели представления:

<Grid x:Name="LayoutRoot" DataContext="{StaticResource VMMain}" Margin="20">
........// all the content
</Grid>

В "Основной видовой модели" я определяю ObservableCollection, которая содержит данные, которые будут отображаться в сетке данных в форме CollectionViewSource. элементы ObservableCollection основаны на "ChildViewModel", который представляет фактические данные и их логику для каждого datarow. Средства. Каждый элемент, добавляемый в ObservableCollection, относится к типу "ChildViewModel". Я разработал его таким образом, потому что я собираюсь отобразить несколько "страниц с подробностями" (на основе выбранной функции или по двойному щелчку ячейки), которые затем позволят просматривать, изменять и обрабатывать данные в другом пользовательском контроле. Прямое изменение в сетке данных не допускается. Таким образом, мне нужно только передать childviewmodel на следующую страницу (или usercontrol) и передать данные и их логику.

private readonly ObservableCollection<childViewModel> _requestList = new ObservableCollection<childViewModel>(); // saves list of "childviewmodel-items"
private readonly ICollectionView _requestCollectionView; // ICollectionView for _requestlist-Collection.

// In the contstructor of the "Main Viewmodel"
var cvs = new CollectionViewSource {Source = _requestList};
                    cvs.SortDescriptions.Add(new SortDescription("RPI_Priority", ListSortDirection.Ascending));
                    cvs.SortDescriptions.Add(new SortDescription("REQ_TestingDate", ListSortDirection.Ascending));
                    _requestCollectionView = cvs.View; 
LoadData(); // db-fetch (entity framework)



/// <summary>
/// Binding to DataGrid!
/// </summary>
public ICollectionView Requests //-> BINDING TO DATAGRID!
{
    get
        {
            return _requestCollectionView;
        }
}

В обработчике события Completed базы данных db заполните наблюдаемую коллекцию дочерней моделью

private void requests_requestLoadingComplete(object sender, EntityResultsArgs<REQ_Request> e)
{
    if (!e.HasError)
    {

       //Fire Event on UI Thread
       Application.Current.RootVisual.Dispatcher.BeginInvoke(() =>
       {
            var o = e.Results.OrderBy(r => r.REQ_TestingDate);
            //clear request list
            _requestList.Clear();
            // add requests to collectionview
            foreach (REQ_Request r in o)
            {
                   // for each record generate a Childviewmodel entry and add it to the observable collection
                   _requestList.Add(new childviewmodel(r));
            }

        });
       }
       else
       {
           // notify if there is any error
           reportError(this,new ResultsArgs(e.Error));
       }

RaiseVMStateChanged();
}

У меня также есть сетка данных на главной странице, которая связана с этим ICollectionView. Источник данных находится в списке "ChildViewModel". Это свойства связаны это:

<sdk:DataGrid AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding Path=Requests}" SelectionMode="Single">
    <sdk:DataGrid.Columns>
        <sdk:DataGridTextColumn Header="ID" Binding="{Binding REQ_ID}" Width="40" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Applikationsname" Binding="{Binding REQ_ApplicationName}" Width="250" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Typ" Binding="{Binding RET_Type}"  Width="70" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Prio" Binding="{Binding RPI_Priority}" Width="70" IsReadOnly="true" />
        <sdk:DataGridTextColumn Header="Status" Binding="{Binding RST_Status}" Width="70" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Sprache" Binding="{Binding SWL_Language}" Width="70" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Version" Binding="{Binding REQ_Version}" Width="70" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Betriebssystem" Binding="{Binding SOS_OS}" Width="150" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="DA" Binding="{Binding Dienstabteilungen}" Width="150" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="AV" Binding="{Binding AV_Fullname}"  Width="150" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Paketierer" Binding="{Binding Paketierer_Fullname}"  Width="150" IsReadOnly="true"/>
        <sdk:DataGridTextColumn Header="Paketierer QS" Binding="{Binding PaketiererQS_Fullname}" Width="150" IsReadOnly="true" />
        <sdk:DataGridTextColumn Header="Abnahmetermin" Binding="{Binding REQ_TestingDate}" Width="150" IsReadOnly="true" />
    </sdk:DataGrid.Columns>
</sdk:DataGrid>

Теперь все это работает отлично и плавно. При нажатии функциональной кнопки я открываю другой пользовательский элемент управления, который инициализируется с помощью экземпляра "Childviewmodel" или его наследником. (с некоторой функцией, которая является дочерним окном, с другой функцией он показывает пользовательский контроль, который отображает все детали и т. д.)

например, дочернее окно:

ShowChildWindow(new PkgRequestDataControl(_vm.CurrentRequest)); --> PkgRequestDataControl inherits from childviewmodel. _vm.CurrentRequest is one single instance of "childviewmodel" that is given

Теперь я изменяю дату в этом дочернем окне и возвращаюсь на главную страницу. По возвращении я вызываю refresh для collectionView (Requests.Refresh();) -> Но данные не обновляются. Ну, иногда это происходит, но в большинстве случаев этого не происходит, пока я не отсортирую измененный столбец таблицы данных 2-3 раза (нажмите на заголовок, чтобы отсортировать и отсортировать.. и отсортировать)

Что я делаю неправильно? Кто-нибудь может помочь? Вся конструкция грязная?

Ура Элиме

1 ответ

Я не уверен, какую именно реализацию ICollectionView вы используете, но в целом ICollectionView.Refresh() обновляет только свойство View с учетом фильтрации, сортировки и группировки. Чтобы ваш пользовательский интерфейс реализовал это изменение, вам все еще нужно реализовать INotifyPropertyChanged и вызвать событие PropertyChanged после вызова Refresh().

Другие вопросы по тегам