2012-02-02 19 views
5

मेरे पास डेटाग्रिड है जो उपयोगकर्ता अंतिम पंक्ति में डेटा दर्ज करके आइटम जोड़ सकता है। मेरे पास एक बटन भी है जो वर्तमान में चयनित आइटम को हटा देता है। लेकिन जब आखिरी (खाली, नई वस्तुओं को जोड़ने के लिए) पंक्ति का चयन किया जाता है, जो चयनित अंतिम आइटम चयनित इटैम में रहता है। इसलिए यदि मैं विंडो खोलता हूं, तो अंतिम पंक्ति का चयन करें और हटाएं बटन दबाएं, यह पहली पंक्ति को हटा देगा, क्योंकि इसे डिफ़ॉल्ट रूप से चुना जाता है, और अंतिम पंक्ति का चयन चयनित इटैम नहीं बदलता है। इससे निपटने का कोई अच्छा तरीका?डब्ल्यूपीएफ डाटाग्रिड चयनित इटैम

स्पष्ट करने के लिए: SelectedItem = "{बाइंडिंग एक्स}" ViewModel में

एक्स जब अंतिम पंक्ति का चयन किया गया परिवर्तन नहीं करता है (सेटर सब पर लागू नहीं है)। मुझे यकीन नहीं है कि चयनित इटैम संपत्ति स्वयं बदलती है, लेकिन मुझे लगता है कि यह नहीं करता है।

जब मैं अंतिम पंक्ति (लाल सीमा) का चयन करता हूं तो अपवाद भी होता है, लेकिन जब मैं डेटा दर्ज करना शुरू करने के लिए इसे फिर से क्लिक करता हूं, तो लाल सीमा निराश होती है। सुनिश्चित नहीं है कि ये दोनों संबंधित हैं।

उत्तर

10

निम्नलिखित उदाहरण चलाएं और आप देखेंगे कि यह क्यों काम नहीं करता है।

XAML:

<Window x:Class="DataGridTest.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"> 
    <DockPanel> 
     <TextBlock DockPanel.Dock="Bottom" Text="{Binding SelectedItem, ElementName=dataGrid}"/> 
     <TextBlock DockPanel.Dock="Bottom" Text="{Binding SelectedItem}"/> 
     <DataGrid x:Name="dataGrid" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/> 
       <DataGridTextColumn Header="Last Name" Binding="{Binding FirstName}"/> 
      </DataGrid.Columns> 
     </DataGrid> 
    </DockPanel> 
</Window> 

कोड-पीछे:

namespace DataGridTest 
{ 
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.ComponentModel; 
    using System.Windows; 

    public partial class MainWindow : Window, INotifyPropertyChanged 
    { 
     private readonly ICollection<Person> items; 
     private Person selectedItem; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      this.items = new ObservableCollection<Person>(); 
      this.items.Add(new Person 
       { 
        FirstName = "Kent", 
        LastName = "Boogaart" 
       }); 
      this.items.Add(new Person 
      { 
       FirstName = "Tempany", 
       LastName = "Boogaart" 
      }); 

      this.DataContext = this; 
     } 

     public ICollection<Person> Items 
     { 
      get { return this.items; } 
     } 

     public Person SelectedItem 
     { 
      get { return this.selectedItem; } 
      set 
      { 
       this.selectedItem = value; 
       this.OnPropertyChanged("SelectedItem"); 
      } 
     } 

     private void OnPropertyChanged(string propertyName) 
     { 
      var handler = this.PropertyChanged; 

      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 

    public class Person 
    { 
     public string FirstName 
     { 
      get; 
      set; 
     } 

     public string LastName 
     { 
      get; 
      set; 
     } 

     public override string ToString() 
     { 
      return FirstName + " " + LastName; 
     } 
    } 
} 

आप, जब चल रहा है 'नई' पंक्ति को चुनकर देख सकते हैं एक प्रहरी मूल्य का कारण बनता है में चयनित आइटम के रूप में स्थापित किया जाना DataGrid। हालांकि, डब्ल्यूपीएफ उस सेंटीनेल आइटम को Person में परिवर्तित करने में असमर्थ है, इसलिए SelectedItem बाध्यकारी रूपांतरित करने में विफल रहता है।

इसे ठीक करने के लिए, आप अपने बाध्यकारी पर कनवर्टर डाल सकते हैं जो सेंटीनेल का पता लगाता है और पता चला जब null देता है। यहाँ एक कनवर्टर है कि ऐसा नहीं करता है है:

namespace DataGridTest 
{ 
    using System; 
    using System.Windows.Data; 

    public sealed class SentinelConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      return value; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value != null && string.Equals("{NewItemPlaceholder}", value.ToString(), StringComparison.Ordinal)) 
      { 
       return null; 
      } 

      return value; 
     } 
    } 
} 

आप देख सकते हैं, यह प्रहरी की ToString() मूल्य के खिलाफ परीक्षण करने के लिए एक दुर्भाग्यपूर्ण आवश्यकता है, क्योंकि यह एक आंतरिक प्रकार है। आप वैकल्पिक रूप से (या इसके अतिरिक्त) जांच सकते हैं कि GetType().NameNamedObject है।

+2

5 साल बाद, लेकिन इसे यहां भी रखा जा सकता है: आप इसे अपने संग्रह पर "{NewItemPlaceholder}" स्ट्रिंग को जलाने की आवश्यकता के बिना, संग्रह View.NewItemPlaceholder के साथ तुलना कर सकते हैं, जो आप कर रहे हैं। –

0

कोड के बिना कहना मुश्किल है, लेकिन मैं निम्नलिखित पर ध्यान देना चाहूंगा।

सुनिश्चित करें कि जब भी कोई आइटम हटा दिया जाता है और यह भी चयनित आइटम है, तो चयनित आइटम को अपने व्यूमोडेल में संपत्ति में बाध्य करने के लिए सेट करें। आपको यह सुनिश्चित करने की आवश्यकता होगी कि संपत्ति के लिए बाध्य आपकी चुनीItem परवाह नहीं है।

0

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

और हमेशा सुनिश्चित करें कि आपके पास सही डेटाैकेंटेक्स्ट है।

उम्मीद है कि मदद करता है।

संबंधित मुद्दे