2009-06-30 15 views
9

मैं सफलतापूर्वक दोवे को डेटा टेम्पलेट में टेक्स्टबॉक्स में एक अवलोकन करने योग्य चयन को बांधने की कोशिश कर रहा हूं। मैं डेटा को ठीक से प्रदर्शित करने के लिए प्राप्त कर सकता हूं, लेकिन मैं यूआई के माध्यम से सूची डेटा को बदलने में असमर्थ हूं। मेरे पास 'मॉडल' नामक एक मॉडल क्लास है जिसमें 'सूची' नामक अवलोकन करने योग्य चयन शामिल है। कक्षा INotifyPropertyChanged इंटरफेस लागू करता है। खोल के लिए xaml यहाँ है। Window1 के ग्रिड के लिए DataContext करने के लिए "theGrid.DataContext = मॉडल" पर सेट हैमैं डेटा टेम्पलेट में टेक्स्टबॉक्स में एक ऑब्जर्जेबल कोलेक्शन कैसे बांध सकता हूं?

<Window x:Class="BindThat.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:BindThat" 
Title="Window1" Height="300" Width="300"> 
<StackPanel x:Name="theGrid"> 
    <GroupBox BorderBrush="LightGreen"> 
     <GroupBox.Header> 
      <TextBlock Text="Group" /> 
     </GroupBox.Header> 
     <ItemsControl ItemsSource="{Binding Path=List}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBox Text="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </GroupBox> 
</StackPanel> 

इस मॉडल वर्ग के लिए कोड है:

class Model : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

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

    private ObservableCollection<string> _list = new ObservableCollection<string>(); 
    public ObservableCollection<string> List 
    { 
     get { return _list; } 
     set 
     { 
      _list = value; 
      NotifyPropertyChanged("List"); 
     } 
    } 

    public Model() 
    { 
     List.Add("why"); 
     List.Add("not"); 
     List.Add("these?"); 
    } 
} 

किसी को सलाह देने के लिए किया जा सका अगर मैं जा रहा हूँ के बारे में यह सही तरीका है?

उत्तर

12

आपको दो तरह से बांधने के लिए एक संपत्ति की आवश्यकता है, इसलिए स्ट्रिंग इसके लिए अच्छा नहीं है।

एक स्ट्रिंग वस्तु में लपेट कर देते हैं:

public class Model 
{ 
    public ObservableCollection<StringObject> List { get; private set; } 
    public Model() 
    { 
     List = new ObservableCollection<StringObject> 
        { 
         new StringObject {Value = "why"}, 
         new StringObject {Value = "not"}, 
         new StringObject {Value = "these"}, 
        }; 
    } 
} 

public class StringObject 
{ 
    public string Value { get; set; } 
} 

और के बजाय मूल्य संपत्ति के लिए बाध्य "।"

इसके अलावा, आपको देखने योग्य संग्रह में बदलाव की अधिसूचना की आवश्यकता नहीं है, इसलिए जब तक आपके मॉडल के पास कुछ अन्य संपत्ति नहीं है, तो इसमें INotifyPropertyChange की आवश्यकता नहीं है। यदि आप चाहते हैं कि आपके आइटम नियंत्रण व्यक्तिगत स्ट्रिंगऑब्जेक्ट्स में परिवर्तनों पर प्रतिक्रिया दें, तो आपको एक स्ट्रिंगऑब्जेक्ट में परिवर्तित किया गया INOTifyProperty जोड़ना चाहिए।

और एक बार फिर, दो तरह से बाध्यकारी डिफ़ॉल्ट है, ताकि आप अपने बंधन में केवल

<TextBox Text="{Binding Path=Value}" /> 

की जरूरत है।

+0

निर्माण! बहुत बहुत धन्यवाद!! – Johnathan1

+1

मुझे नहीं लगता कि आपको टेक्स्ट प्रॉपर्टी में "पथ =" डालना होगा, 'टेक्स्ट = "{बाइंडिंग वैल्यू}" ' – user1069816

+0

भी काम करेगा क्यों एकल स्ट्रिंग प्रॉपर्टी काम करती है लेकिन सूची नहीं? – YukiSakura

1

मेरा मानना ​​है कि आपको काम करने के लिए बाध्यकारी दोवे के लिए निर्भरता ऑब्जेक्ट से अपने संग्रह आइटम प्राप्त करने की आवश्यकता है। कुछ की तरह:

public class DependencyString: DependencyObject { 
    public string Value { 
     get { return (string)GetValue(ValueProperty); } 
     set { SetValue(ValueProperty, value); } 
    } 

    public static readonly DependencyProperty ValueProperty = 
     DependencyProperty.Register("Value", typeof(string), typeof(DependencyString), new UIPropertyMetadata("")); 

    public override string ToString() { 
     return Value; 
    } 

    public DependencyString(string s) { 
     this.Value = s; 
    } 
} 

public class Model { 
    private ObservableCollection<DependencyString> _list = new ObservableCollection<DependencyString>(); 
    public ObservableCollection<DependencyString> List { 
     get { return _list; } 
    } 

    public Model() { 
     List.Add(new DependencyString("why")); 
     List.Add(new DependencyString("not")); 
     List.Add(new DependencyString("these?")); 
    } 
} 

... मेरे लिए

<StackPanel x:Name="theGrid"> 
    <GroupBox BorderBrush="LightGreen"> 
     <GroupBox.Header> 
      <TextBlock Text="Group" />   
     </GroupBox.Header> 
     <ItemsControl ItemsSource="{Binding Path=List}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBox Text="{Binding Path=Value, Mode=TwoWay}"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </GroupBox> 
</StackPanel> 
+0

मुझे नहीं लगता कि इस मामले में निर्भरता प्रॉपर्टी की आवश्यकता है। यह केवल तभी जरूरी है जब आप उस संपत्ति को किसी अन्य चीज़ से बांधना चाहते हैं। – Andy

+0

अब दोनों विचारों के आधार पर, मैं अपने आवेदन के लिए एक समाधान के साथ आने में सक्षम था। आपके पोस्ट के लिए शुक्रिया!! – Johnathan1

+0

इससे मुझे बहुत अच्छा मदद मिली, धन्यवाद। जिस भाग को मैं याद कर रहा था वह मोड = टूवे सेट करना था ताकि उपयोगकर्ता ने बदलाव किए जाने के बाद listbox.itemsSource से अपडेट किए गए डेटा तक पहुंच सकें। – javram