Silverlight - MVVM:绑定到ICollectionView的Datagrid填充“ChildViewModel”不会刷新数据

时间:2012-05-21 07:52:14

标签: silverlight mvvm icollectionview

我找不到类似的案例,所以我很挣扎。我是Silverlight的新手,并且正在努力刷新ICollectionView。 Refresh-Method实际上不会刷新我的数据网格中的数据,尽管它们已被更改(在调试器中看到它并在对数据网格进行排序几次后最终会反映更改)。我担心我完全弄乱了我的应用程序的整个构造。我认为这个问题与我实现的“MainViewModel-ChildViewModel”原理有某种关系。

这是我的构造: 在我的主页面中,我添加了一个“主视图模型”作为资源。

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

Grid LayoutRoot然后将它的datacontext设置为此viewmodel:

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

在“主视图模型”中,我定义了一个ObservableCollection,它保存将以CollectionViewSource的形式显示在数据网格中的数据。 ObservableCollection项基于“ChildViewModel”,它表示每个数据行的实际数据和逻辑。 意思是:添加到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;
        }
}

在db-fetch的Completed eventhandler中填充带有childviewmodel的observablecollection

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的数据网格。 itemsource是“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”的instanze或它的继承初始化的usercontrol。 (某些函数是一个带有其他函数的子窗口,它显示了一个显示所有细节的用户控件等)

例如childwindow:

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

现在我修改此子窗口中的日期并返回主页。 返回时,我在collectionView上调用refresh(Requests.Refresh();) - &gt;但数据不会刷新。 嗯..有时它确实如此,但大部分时间它都没有直到我将数据网格的更改的coloum排序2-3次(点击标题进行排序和排序......并排序)

我做错了什么?有人可以帮忙吗?整个构造是否凌乱?

干杯 Elime

1 个答案:

答案 0 :(得分:0)

我不确定你正在使用哪个ICollectionView实现,但一般来说ICollectionView.Refresh()只刷新View属性,将过滤,排序和分组考虑在内。要让您的UI实现此更改,您仍需要在调用Refresh()之后实现INotifyPropertyChanged并引发PropertyChanged事件。