2009-06-30 37 views
9

我想成功TwoWay將一個ObservableCollection綁定到DataTemplate中的TextBoxes。我可以正確顯示數據,但我無法通過用戶界面更改列表數據。我有一個名爲'model'的Model類,其中包含一個名爲'List'的ObservableCollection。該類實現INotifyPropertyChanged接口。這是shell的xaml。在DataContext的窗口1的網格設置爲「theGrid.DataContext =模型」如何將ObservableCollection綁定到DataTemplate中的TextBoxes?

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

,並綁定到Value屬性,而不是 「」另外,您不需要通知可觀察集合中的更改,因此,除非您的模型具有其他一些屬性,它不需要具有INotifyPropertyChange。如果你希望你的ItemsControl對單個StringObject中的變化做出反應,那麼你應該將INotifyPropertyChanged添加到一個StringObject中。

而且再次,雙向綁定是默認的,所以在你的綁定只需要

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

+0

對我的作品!非常感謝!! – Johnathan1 2009-06-30 21:31:12

+1

我不認爲你需要在Text屬性中放置「Path =」,也可以使用Text =「{Binding Value}」 – user1069816 2014-12-23 17:09:37

1

我相信你需要從DependencyObject派生你的收集項目,以便雙向綁定工作。喜歡的東西:

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> 
相關問題