如何将 ObservableCollection 绑定到 DataTemplate 中的文本框?
Posted
技术标签:
【中文标题】如何将 ObservableCollection 绑定到 DataTemplate 中的文本框?【英文标题】:How can I bind an ObservableCollection to TextBoxes in a DataTemplate? 【发布时间】:2010-11-06 22:00:37 【问题描述】:我正在尝试成功将一个 ObservableCollection 绑定到 DataTemplate 中的 TextBoxes。我可以让数据正确显示,但我无法通过 UI 更改列表数据。我有一个名为“模型”的模型类,其中包含一个名为“列表”的 ObservableCollection。该类实现 INotifyPropertyChanged 接口。这是shell的xaml。 Window1 的网格的 DataContext 设置为“theGrid.DataContext=model”
<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?");
任何人都可以建议我是否以正确的方式解决这个问题?
【问题讨论】:
【参考方案1】:你需要一个属性来绑定两种方式,所以字符串不适合这个。
将其包装在一个字符串对象中,如下所示:
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 属性而不是“。”
另外,你不需要通知 observable 集合的变化,所以在你的模型有它自己的一些其他属性之前,它不需要有 INotifyPropertyChange。如果您希望您的 ItemsControl 对单个 StringObjects 中的更改做出反应,那么您应该将 INotifyPropertyChanged 添加到 StringObject。
再一次,双向绑定是默认的,所以你只需要
<TextBox Text="Binding Path=Value" />
在您的绑定中。
【讨论】:
为我工作!非常感谢!! 我认为你不需要在 Text 属性中添加 "Path=",Text="Binding Value"
也可以
为什么单个字符串属性有效但 List我相信您需要从 DependencyObject 派生您的集合项才能使 TwoWay 绑定工作。比如:
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>
【讨论】:
我认为在这种情况下不需要 DependencyProperty。仅当您想将该属性绑定到其他东西时才需要这样做。 现在基于这两个想法,我能够为我的应用程序提出一个解决方案。谢谢你的帖子!! 这对我帮助很大,谢谢。我缺少的部分是设置 Mode=TwoWay 以便在用户进行更改后我可以从 listbox.itemsSource 访问更新的数据。【参考方案3】:xaml 视图:
<ItemsControl ItemsSource="Binding List">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在构造函数后面的代码中:
DataContext = new ViewModel();
在 ViewModel 类中:
class ViewModel : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
private ObservableCollection<StringObject> _List = new ObservableCollection<StringObject>();
public ObservableCollection<StringObject> List
get return _List;
set
_List = value;
NotifyPropertyChanged("List");
public ViewModel()
List = new ObservableCollection<StringObject>
new StringObject Value = "why",
new StringObject Value = "not",
new StringObject Value = "these"
;
public class StringObject
public string Value get; set;
注意string
类型的集合不起作用,您必须使用对象 => StringObject
【讨论】:
以上是关于如何将 ObservableCollection 绑定到 DataTemplate 中的文本框?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 WPF DataGrid 绑定到 ObservableCollection
如何将 ObservableCollection 与 datagrid WPF 绑定
将 ObservableCollection 保存到文件 (.txt)
C#如何将实体框架实体与ObservableCollection一起使用