0

同様のケースはまだ見つからないので、苦労しています。私は Silverlight のグリーンホーンであり、ICollectionView の更新に苦労しています。Refresh-Method は、データグリッド内のデータが変更されているにもかかわらず、実際にはデータを更新しません (デバッガーで確認し、データグリッドを数回並べ替えた後、最終的に変更が反映されます)。残念ながら、アプリケーションの構成全体を完全に台無しにしてしまいました。この問題は、私が実装した「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>

「メイン ビューモデル」では、CollectionViewSource の形式でデータグリッドに表示されるデータを保持する ObservableCollection を定義します。ObservableCollection アイテムは、実際のデータと各データ行のロジックを表す「ChildViewModel」に基づいています。意味: ObservableCollection に追加される各アイテムは、「ChildViewModel」のタイプです。そのように設計したのは、(選択した関数またはセルのダブルクリックに基づいて) いくつかの「詳細ページ」を表示し、別のユーザーコントロールのデータを表示、変更、および操作できるようにするためです。データグリッドでの直接の変更は許可されていません。そうすれば、childviewmodel を次のページ (またはユーザー コントロール) に渡すだけで、データとそのロジックが渡されます。

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 イベントハンドラで、observablecollection に childviewmodel を入力します。

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」のインスタンスまたはその継承で初期化された別のユーザーコントロールが開きます。(子ウィンドウである関数と他の関数を使用すると、すべての詳細などを表示するユーザーコントロールが表示されます)

たとえば、子ウィンドウ:

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

ここで、この子ウィンドウの日付を変更してメインページに戻ります。戻ったら、collectionView (Requests.Refresh();) で refresh を呼び出します -> しかし、データは更新されません。まあ..時々そうですが、ほとんどの場合、データグリッドの変更された列を2〜3回ソートするまでそうではありません(ヘッダーをクリックして並べ替えと並べ替え..および並べ替えを行います)

私は何を間違っていますか?誰でも助けることができますか?コンストラクト全体が乱雑ですか?

乾杯エライム

4

1 に答える 1

0

使用している ICollectionView の実装が正確にはわかりませんが、一般に ICollectionView.Refresh() は、フィルタリング、並べ替え、およびグループ化を考慮して View プロパティのみを更新します。UI がこの変更を認識できるようにするには、INotifyPropertyChanged を実装し、Refresh() を呼び出した後に PropertyChanged イベントを発生させる必要があります。

于 2012-05-25T16:07:04.603 に答える