2012-07-19 12 views
5

मैं अवधारणा के निम्न सबूत है:क्या यह एक डब्ल्यूपीएफ डेटाग्रिड बग है?

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; } 
} 
} 

, एप्लिकेशन निष्पादित शीर्ष पर कुछ बॉक्स को अनचेक करें, नीचे स्क्रॉल करें, कुछ बदल फिर से बॉक्स और स्क्रॉल करें। Voilá, चेकबॉक्स फिर से चेक कर रहे हैं!

क्या मुझे कुछ याद आ रहा है या क्या मुझे माइक्रोसॉफ्ट में एक बग भरना चाहिए?

संपादित करें: आपके प्रतिक्रियाओं के लिए धन्यवाद लेकिन यह टेक्स्टबॉक्स के साथ इनोटिफ़ी या चेकबॉक्स से संबंधित नहीं है और इन्हें समानता होती है। स्क्रॉल करने के बाद आपको चेकबॉक्स पर क्लिक करने की आवश्यकता नहीं है, बस कुछ अनचेक करें, स्क्रॉल करें, स्क्रॉल करें और वॉयला, फिर से जांच की जाती है।

<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> 

और पीछे कोड: क्योंकि यह काम कर रहा है या नहीं जहाँ भी VirtualRows हैं की उम्मीद तरीका नहीं है

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

क्या आपका परिणाम बदलता है यदि आप 'INOTifyPropertyChanged' से 'डेटा' उत्तराधिकारी बनाते हैं और संपत्ति परिवर्तन अधिसूचनाओं का उपयोग करते हैं? – Rachel

+0

रीसाइक्लिंग बंद करने का प्रयास करें। क्या सेट बुलाया जाता है? यदि UpdateSourceTrigger = "PropertyChanged" नहीं है। और राहेल की तरह इरोटिफा ने कहा। – Paparazzi

+0

मैं राहेल ने सुझाव दिया कि मैं कोशिश करूंगा। – ecMode

उत्तर

1

अंत में मैं माइक्रोसॉफ्ट में एक दोष डाल देने के बाद इस कोड की जाँच करें उपयोग किया गया।

बग रिपोर्ट here

6

यह समस्या रीसाइक्लिंग से संबंधित नहीं है। वास्तव में, रीसाइक्लिंग को अक्षम करने से वास्तविक समस्या छिप जाती है: आपकी Data ऑब्जेक्ट गुण कभी अपडेट नहीं होते हैं। Enabled या Text सेटर में ब्रेकपॉइंट सेट करने का प्रयास करें और आप देखेंगे कि जब आप टेक्स्ट बदलते हैं या बॉक्स को चेक/अनचेक करते हैं तो कुछ भी नहीं होगा। जब आप दूर और पीछे स्क्रॉल करते हैं, तो संपत्ति ऑब्जेक्ट से फिर से पढ़ी जाती है, और चूंकि यह नहीं बदला है, इसलिए Enabled संपत्ति से मेल खाने के लिए चेकबॉक्स सही ढंग से अपडेट किया गया है।

DataGrid डिफ़ॉल्ट रूप से डिस्प्ले मोड में सभी पंक्तियों के लिए है, उपयोगकर्ता वर्तमान में चयनित पंक्ति पर संपादन मोड में स्विच करने के साथ स्विच करने के लिए है। मान तब तक प्रतिबद्ध नहीं होते जब तक कि उपयोगकर्ता पूरी पंक्ति को मान्य न करे।

दृश्यों के पीछे, एक अंतर्निहित BindingGroup पूरी पंक्ति के लिए बनाया गया है, प्रभावी ढंग से सभी बाइंडिंग को UpdateSourceTrigger.Explicit पर सेट कर रहा है। यह बाध्यकारी समूह तब किया जाता है जब उपयोगकर्ता पंक्ति को संपादित कर लेता है। आपके मामले में, चूंकि BeginEdit नहीं है, तो कोई भी CommitEdit नहीं होगा और मान कभी अपडेट नहीं होंगे। इस तरह के एक ListView रूप

  • एक और नियंत्रण का प्रयोग करें कि यह "स्विच मोड संपादित करने के लिए" व्यवहार नहीं है,:

    आप यहाँ कई समाधान है।

  • हर बंधन पर UpdateSourceTriggerPropertyChanged करने के लिए या LostFocus बाध्य करें।
  • बदलें DataGrid व्यवहार का अनुपालन करने के लिए उपयोगकर्ता ग्रिड का उपयोग कैसे करता है।