Wpf 使用ItemsControl进行双向绑定
我正在尝试编写一个具有ItemsControl的用户控件,它的ItemsTemplate包含一个允许双向绑定的文本框。但是,我的代码中肯定有错误,因为绑定似乎只在Mode=OneWay的情况下工作。这是我的项目的一个相当简化的摘录,但它仍然包含以下问题:Wpf 使用ItemsControl进行双向绑定,wpf,binding,itemscontrol,Wpf,Binding,Itemscontrol,我正在尝试编写一个具有ItemsControl的用户控件,它的ItemsTemplate包含一个允许双向绑定的文本框。但是,我的代码中肯定有错误,因为绑定似乎只在Mode=OneWay的情况下工作。这是我的项目的一个相当简化的摘录,但它仍然包含以下问题: <UserControl x:Class="ItemsControlTest.UserControl1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentati
<UserControl x:Class="ItemsControlTest.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<Grid>
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=.}"
x:Name="myItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Mode=TwoWay,
UpdateSourceTrigger=LostFocus,
Path=.}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Click="Button_Click"
Content="Click Here To Change Focus From ItemsControl" />
</StackPanel>
</Grid>
</UserControl>
以下是上述控件的隐藏代码:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.ObjectModel;
namespace ItemsControlTest
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public ObservableCollection<string> MyCollection
{
get { return (ObservableCollection<string>)GetValue(MyCollectionProperty); }
set { SetValue(MyCollectionProperty, value); }
}
// Using a DependencyProperty as the backing store for MyCollection. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyCollectionProperty =
DependencyProperty.Register("MyCollection",
typeof(ObservableCollection<string>),
typeof(UserControl1),
new UIPropertyMetadata(new ObservableCollection<string>()));
public UserControl1()
{
for (int i = 0; i < 6; i++)
MyCollection.Add("String " + i.ToString());
InitializeComponent();
myItemsControl.DataContext = this.MyCollection;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Insert a string after the third element of MyCollection
MyCollection.Insert(3, "Inserted Item");
// Display contents of MyCollection in a MessageBox
string str = "";
foreach (string s in MyCollection)
str += s + Environment.NewLine;
MessageBox.Show(str);
}
}
}
使用系统;
使用System.Windows;
使用System.Windows.Controls;
使用System.Collections.ObjectModel;
命名空间项控件测试
{
///
///UserControl1.xaml的交互逻辑
///
公共部分类UserControl1:UserControl
{
公共可观测集合MyCollection
{
get{return(ObservableCollection)GetValue(MyCollectionProperty);}
set{SetValue(MyCollectionProperty,value);}
}
//使用DependencyProperty作为MyCollection的备份存储。这将启用动画、样式、绑定等。。。
公共静态只读DependencyProperty MyCollectionProperty=
DependencyProperty.Register(“MyCollection”,
类型(可观测采集),
类型(用户控制1),
新的UIPropertyMetadata(新的ObservableCollection());
公共用户控制1()
{
对于(int i=0;i<6;i++)
MyCollection.Add(“字符串”+i.ToString());
初始化组件();
myItemsControl.DataContext=this.MyCollection;
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
//在MyCollection的第三个元素后插入字符串
MyCollection.插入(3,“插入项”);
//在消息框中显示MyCollection的内容
字符串str=“”;
foreach(MyCollection中的字符串s)
str+=s+Environment.NewLine;
MessageBox.Show(str);
}
}
}
最后,这里是主窗口的xaml:
<Window x:Class="ItemsControlTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:ItemsControlTest"
Title="Window1" Height="300" Width="300">
<Grid>
<src:UserControl1 />
</Grid>
</Window>
好了,就这些。我不知道为什么编辑文本框。窗口中的文本属性似乎不会更新代码背后绑定的源属性,即MyCollection。点击按钮几乎会导致问题直视我;)请帮助我理解我的错误所在
塔克斯
Andrew好的,我认为导致此问题的原因是您直接绑定到
字符串。字符串在C中是不可变的,因此当您更改文本时,它无法更改ObservableCollection
中的基础字符串。要解决这个问题,只需创建一个模型类来保存字符串数据,然后将TextBox.Text
绑定到该类中的属性。以下是一个例子:
public partial class BindingToString : Window
{
public BindingToString()
{
MyCollection = new ObservableCollection<TestItem>();
for (int i = 0; i < 6; i++)
MyCollection.Add(new TestItem("String " + i.ToString()));
InitializeComponent();
myItemsControl.DataContext = this.MyCollection;
}
public ObservableCollection<TestItem> MyCollection
{
get;
set;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// Display contents of MyCollection in a MessageBox
string str = "";
foreach (TestItem s in MyCollection)
str += s.Name + Environment.NewLine;
MessageBox.Show(str);
}
}
public class TestItem
{
public string Name
{
get;
set;
}
public TestItem(string name)
{
Name = name;
}
}
现在,TextBox
被绑定到TestItem
上的Name
路径,这个绑定可以正常工作并按预期修改集合。这太棒了,Charlie,看起来你成功了。你的建议很有效!
<Window x:Class="TestWpfApplication.BindingToString"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BindingToString " Height="300" Width="300">
<Grid>
<StackPanel>
<ItemsControl ItemsSource="{Binding}"
x:Name="myItemsControl">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button Click="Button_Click"
Content="Click Here To Change Focus From ItemsControl" />
</StackPanel>
</Grid>