8

編集済み: MainWindow.xaml、MainWindow.xaml.cs、およびMainWindowViewModel.csの3つのファイル(以下にリスト)を使用して、新しいVS2010WPFアプリケーションを作成しました。誰かが本当に助けになったと感じたら、数秒で問題を再現できます(コピー/貼り付け)。アプリを実行すると、DataGridは間違った文字列「OldCollection」を表示します。ItemsSourceバインディングをMyCollectionに変更すると、正しい「NewCollection」が表示されます。

完全な説明: 最初は、ItemsSourceがMyCollectionにバインドされたDataGridがありました。新しいObservableCollection<>をMyCollectionに割り当てるUpdateCollectionメソッドが必要です。MyCollectionにNotifyPropertyChangeを追加すると、UIが更新されます。

次に、グループ化を有効にするためにCollectionViewSourceを導入する必要がありました。UIがMyCollectionViewにバインドされているため、UpdateCollectionの呼び出しは効果がありません。デバッガーは、MyCollectionViewに常に最初のMyCollectionが含まれていることを確認します。NewCollectionをビューに反映させるにはどうすればよいですか?View.Refresh()、Binding CollectionViewSource、およびその他の無数の戦略を試しました。

注:主に他の人は、更新を呼び出さずにビューを更新(グループ化/並べ替え)しないコレクションアイテムへの変更に関心があります。私の問題は、まったく新しいコレクションをCollectionViewSourceに割り当てているのですが、ビュー/UIが変更されないことです。

// MainWindow.xaml
<Window x:Class="CollectionView.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid Name="grid" ItemsSource="{Binding MyCollectionView}" />
    </Grid>
</Window>

//MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;

namespace CollectionView
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
}

//MainWindowViewModel.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.ComponentModel;

namespace CollectionView
{
    class MainWindowViewModel : INotifyPropertyChanged
    {
        public MainWindowViewModel()
        {
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "OldCollection" } };

            MyCollectionViewSource = new CollectionViewSource();

            // Bind CollectionViewSource.Source to MyCollection
            Binding MyBind = new Binding() { Source = MyCollection };
            BindingOperations.SetBinding(MyCollectionViewSource, CollectionViewSource.SourceProperty, MyBind);

            // The DataGrid is bound to this ICollectionView
            MyCollectionView = MyCollectionViewSource.View;

            // This assignment here to demonstrate that View/UI does not update to show "NewCollection"
            MyCollection = new ObservableCollection<MyObject>() { new MyObject() { TestString = "NewCollection" } };
        }

        // Collection Property
        // NotifyPropertyChanged added specifically to notify of MyCollection re-assignment
        ObservableCollection<MyObject> _MyCollection;
        public ObservableCollection<MyObject> MyCollection
        {
            get { return _MyCollection; }
            set
            {
                if (value != _MyCollection)
                {
                    _MyCollection = value;
                    NotifyPropertyChanged("MyCollection");
                }
            }
        }

        public CollectionViewSource MyCollectionViewSource { get; private set; }
        public ICollectionView MyCollectionView { get; private set; }

        // Method updates MyCollection itself (Called via ICommand from another ViewModel)
        public void UpdateCollection(ObservableCollection<MyObject> NewCollection)
        {
            MyCollection = NewCollection;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

    class MyObject
    {
        public string TestString { get; set; }
    }
}

ありがとう、

4

3 に答える 3

8

次の2つの解決策のいずれかを選択します。

まず、を取得して(グループ化、並べ替え)を1回ObservableCollection作成できます。ICollectionViewを置き換える代わりに、新しいコレクションのアイテムをObservableCollection使用して追加できます。.Clear()これには、グループ化と並べ替えを壊さないという追加のボーナスがあります。

2番目のアプローチ:あなたがあなたを置き換えるときはいつでも、あなたはソートとグループ化のためObservableCollectionに新しいものを作成しなければなりません 。ICollectionView

 this._view = (ICollectionView)CollectionViewSource.GetDefaultView(this.MyCollection);

DefaultViewを使用すると、コレクションにバインドできます。

 <DataGrid Name="grid" ItemsSource="{Binding MyCollection}" />

そして、CollectionViewSourceコードバインディングのものを捨てることができます。

于 2012-04-11T08:03:21.320 に答える
0

問題は間違いなく、ソースをMyCollectionプロパティにバインドしておらず、一度割り当てただけで、二度と更新されないという事実です。

次のようなことをする必要があります。

MyCollectionViewSource = new CollectionViewSource();
Binding binding = new Binding();
binding.Source = MyCollection;
BindingOperations.SetBinding( MyCollectionViewSource , 
                              CollectionViewSource.SourceProperty, 
                              binding );

上記が微調整せずにすぐに機能しない場合は、お詫び申し上げます。これは、xamlで設定したもののタイプです。これは、xamlの方がはるかに簡単だからです。

<CollectionViewSource Source="{Binding MyCollection}" />

関連項目:CollectionView.Sourceのバインディングを変更するにはどうすればよいですか?

于 2012-04-10T17:39:30.450 に答える
0

バインディングが機能していないという事実は、信じられないほど奇妙です。Xceed DataGridCollectionViewSourceでまったく同じ問題が発生しましたが、Xceedが失敗したためだと思いました。

私の解決策は、基になるコレクションが置き換えられるたびに実際に新しいDataGridCollectionViewSourceを作成し、プログラムで再構成してから、myDataGrid.Sourceプロパティを更新して新しいDataGridCollectionViewSourceを指すようにすることでした。その回避策は確かに機能しますが、それは機能するはずのバインディングの目的を完全に無効にします。

void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    //Xceed DataGridCollectionView are terrible and do not update when the bound table changes, so we need to replace them each change.
   if (e.PropertyName == "MyCollection")
   {
       DataGridCollectionView GridView = new DataGridCollectionView(MyViewModel.MyCollection.DefaultView);
       GridView.SortDescriptions.Add(new SortDescription("DataSetID", ListSortDirection.Ascending));
       uiMyCollectionGrid.ItemsSource = GridView;
   }
}

たぶん、このブルートフォースソリューションはあなたの問題を解決することができますか?とても汚いので、まだこれを考慮したくないのなら、私は理解しています。

于 2012-04-10T19:54:11.683 に答える