2012-07-19 28 views
5

私がコンセプトの、次の証拠がありますこれはWPF Datagridのバグですか?

XAMLウィンドウ:背後

<Window x:Class="WpfApplication1.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"> 

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" > 
    <DataGrid.Columns> 
     <DataGridTextColumn Binding="{Binding Name}" /> 
     <DataGridTemplateColumn > 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <CheckBox IsChecked="{Binding Mode=TwoWay, Path=Enabled}" /> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 
</Window> 

コード:

using System.Collections.ObjectModel; 
using System.Windows; 

namespace WpfApplication1 
{ 
public partial class MainWindow : Window 
{ 
    public ObservableCollection<Data> Items { get; private set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Items = new ObservableCollection<Data>(); 
     this.DataContext = this; 
     for (int index = 0; index < 30; index++) 
     { 
      this.Items.Add(new Data() {Enabled = true }); 
     } 
    } 
} 

public class Data 
{ 
    public bool Enabled { get; set; } 
} 
} 

、アプリを実行上部にあるいくつかのボックスのチェックを外し、スクロールダウンし、一部を変更しますボックスをもう一度スクロールアップします。チェックボックスが再びチェックされます。

私に何かが見つからないか、Microsoftにバグを記入する必要がありますか?

EDIT:ありがとうございますが、INotifyやCheckbox、TextBoxとは関係ないので、同じことが起こります。スクロールした後にチェックボックスをクリックする必要はありません。いくつかのチェックボックスをオフにするだけでスクロールアップし、スクロールアップして、再度確認します。このコードをチェックしてください:

<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" > 
    <DataGrid.Columns> 
     <DataGridTemplateColumn > 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <CheckBox IsChecked="{Binding Mode=TwoWay, Path=Enabled}" /> 
         <TextBox Text="{Binding Text}" /> 
        </StackPanel> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 
</Window> 

そして、背後にあるコード:

using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 

namespace WpfApplication1 
{ 
public partial class MainWindow : Window 
{ 
    public ObservableCollection<Data> Items { get; private set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     this.Items = new ObservableCollection<Data>(); 
     this.DataContext = this; 
     for (int index = 0; index < 30; index++) 
     { 
      this.Items.Add(new Data() { Enabled = true, Text = index.ToString() }); 
     } 
    } 
} 

public class Data : INotifyPropertyChanged 
{ 
    private bool _enabled; 
    public bool Enabled 
    { 
     get { return _enabled; } 
     set 
     { 
      if (value != _enabled) 
      { 
       _enabled = value; 
       this.OnPropertyChanged("Enabled"); 
      } 
     } 
    } 

    private string _text; 
    public string Text 
    { 
     get { return _text; } 
     set 
     { 
      if (value != _text) 
      { 
       _text = value; 
       this.OnPropertyChanged("Text"); 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string name) 
    { 
     if (this.PropertyChanged != null) 
     { 
      this.PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 

    #endregion 
} 
} 
+1

'Data'を' INotifyPropertyChanged'から継承し、プロパティ変更通知を使用すると結果は変わりますか? – Rachel

+0

リサイクルをオフにしてください。セットが呼び出されますか? UpdateSourceTrigger = "PropertyChanged"でなければそしてレイチェルが言ったように不意打ちをする。 – Paparazzi

+0

私はレイチェルが提案したことを試してみる。 – ecMode

答えて

1

これはどこかではないVirtualRowsがある作業の予想される方法ではありませんので、最後に、私はMicrosoftの欠陥を入力しました中古。

here

6

この問題はバグレポートはリサイクルとは関係ありません。実際、リサイクルを無効にすると実際の問題は隠されます。Dataオブジェクトのプロパティは決して更新されません。 EnabledまたはTextセッターにブレークポイントを設定しようとすると、テキストを変更したり、チェックボックスをオンまたはオフにしても何も起こりません。離れてスクロールすると、プロパティはオブジェクトから読み込まれ、変更されていないため、チェックボックスはEnabledプロパティに一致するように正しく更新されます。

DataGridは、デフォルトで表示モードのすべての行を持つことを意味し、ユーザーは必要なときに現在選択されている行の編集モードに切り替わります。ユーザーが行全体を検証するまで、値はコミットされません。

暗黙のうちに暗黙のBindingGroupが行全体に対して作成され、すべてのバインディングが効果的にUpdateSourceTrigger.Explicitに設定されます。このバインディング・グループは、ユーザーが行の編集を完了したときにコミットされます。あなたのケースでは、BeginEditが存在しないので、CommitEditは存在せず、値は更新されません。

あなたはここにいくつかのソリューションがあります。

  • などListViewとして、この「編集モードに切り替える」振る舞いを持っていない別のコントロールを使用します。
  • すべてのバインディングでUpdateSourceTriggerPropertyChangedまたはLostFocusを強制します。
  • グリッドを使用してDataGridの動作に準拠する方法を変更します。