2010-11-24 8 views
1

次のコードをコンパイルして実行すると、行を選択または選択解除すると、出力ウィンドウに行が書き込まれることになります。そのコードは信じるように導くだろう)。WPFバインディングが短時間で失敗する

矢印キーを使用してグリッドの選択した行を短時間変更した後(上向き矢印と下向き矢印をそれぞれ押してデータセット全体を数回走査する)グリッドの行を循環している間でも、出力メッセージは停止します。

私はthis answerで与えられたものと同様のものを達成しようとしています。

私は絶対に困惑しています。私のグリッドのバインディングが自動的に失敗する原因は何ですか?ここにあるすべての助けが大いに評価されるでしょう!また、誰かがこれを再現する時間があれば、あなたの調査結果をコメントしてください。

XAML:

<Window x:Class="WpfApplication1.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <DataGrid Name="TheGrid"> 
      <DataGrid.Resources> 
       <Style TargetType="{x:Type DataGridRow}"> 
        <Setter Property="IsSelected" 
          Value="{Binding Mode=TwoWay, Path=IsSelected}"/> 
       </Style> 
      </DataGrid.Resources> 
      <DataGrid.Columns> 
       <DataGridTextColumn IsReadOnly="True" 
            Binding="{Binding Name}" Header="Name"/> 
      </DataGrid.Columns> 
     </DataGrid> 
    </Grid> 
</Window> 

コードビハインド:

using System; 
using System.ComponentModel; 
using System.Linq; 
using System.Windows; 

namespace WpfApplication1 { 
    public partial class Window1 : Window { 
     public Window1() { 
      InitializeComponent(); 
      TheGrid.ItemsSource = Enumerable.Range(1, 100) 
           .Select(i => new MyClass("Item " + i)); 
     } 
    } 

    public class MyClass : INotifyPropertyChanged { 
     public string Name { get; private set; } 

     private bool m_IsSelected; 
     public bool IsSelected { 
      get { 
       return m_IsSelected; 
      } 
      set { 
       if (m_IsSelected != value) { 
        m_IsSelected = value; 
        Console.WriteLine(Name + ": " + m_IsSelected); 
        PropertyChanged(this, 
         new PropertyChangedEventArgs("IsSelected")); 
       } 
      } 
     } 

     public MyClass(string name) { 
      Name = name; 
     } 

     public event PropertyChangedEventHandler PropertyChanged = 
                  delegate { }; 
    } 
} 

事前に感謝します!

EDIT:

  • RowStyleSelector プロパティを使用してDataGridRow スタイルを適用しようとしました - 失敗。

  • Row_LoadingRow_Unloadingイベントを使用してスタイルを適用しようとしました - 失敗します。

  • 、カスタム MultiSelectCollectionViewを使用してみました - 失敗

  • VirtualizingStackPanel.IsVirtualizing="False"を設定しようとしました(DataGridコントロールでは動作しませんでした) - (数百行とunusably遅い)失敗

  • VirtualizingStackPanel.VirtualizationModeをいじってみました(標準またはリサイクル) - 失敗します。

以下の私のコメントの1で述べたように、包括的な問題がselectedItemsのが読み取り専用されているので、私は、することができない私のViewModelにデータグリッドのselectedItemsのプロパティをバインドする必要がありますが、ということです。

純粋なMVVMの何か、これのためのすぐに使える解決策がありますが、これまでのところ、私を逃してしまいました!

+0

私はVSをクラッシュできました。ダブルクリックすると、行を並べ替えるときと同じように、時々戻ってきます。おそらく仮想化の問題に関係しています。 – xdumaine

+0

オーバーアーチングの問題は、DataGridコントロールを使用してMVVM中心の方法で複数の選択を行うことができないことです(SelectedItemsは読み取り専用であり、バインドできません)。この男のソリューションは、私が必要としているようです:http://grokys.blogspot.com/2010/07/mvvm-and-multiple-selection-part-iii.htmlまだ実装されていません。私はそれが働いている(または動作していない...) – Pwninstein

+0

私は以前のコメントでリンクされたソリューションは、WPF DataGridコントロールでは全く動作しませんでしたので、コメントするつもりだ...いいえサイコロ。 – Pwninstein

答えて

1

これを試したところ、同じ動作でした。私は、次のように仮想化できないようにDataGridを変更して問題を解決できました:<DataGrid Name="TheGrid" AutoGenerateColumns="False" VirtualizingStackPanel.IsVirtualizing="False">

詳細はMSDN forum postを参照してください。

+0

恐ろしい!仮想化を無効にしても、私のグリッドはどのように大規模なデータセットになるのだろうか...とにかく、うまくいきました!ありがとう! – Pwninstein

+0

大きなデータセットで試してみましたが、フィルタリングにはFOREVERが必要です!どのように私は仮想化でこの動作を回避することができる任意のアイデアは、オン? – Pwninstein

+0

仮想化を元に戻すことができます.2つのモードがあり、もう1つは動作する可能性があります。VirtualizingStackPanel.VirtualizationMode = Standard and Recycling –