我正在尝试编写一个具有 ItemsControl 的用户控件,其中 ItemsTemplate 包含一个允许双向绑定(bind)的 TextBox。但是,我一定是在我的代码的某个地方犯了一个错误,因为绑定(bind)似乎只像 Mode=OneWay 一样工作。这是我项目的一个非常简化的摘录,但它仍然包含问题:
<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);
}
}
}
最后,这是主窗口的 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>
嗯,就是这样。我不确定为什么在窗口中编辑 TextBox.Text 属性似乎不会更新后面代码中绑定(bind)的源属性,即 MyCollection。单击按钮几乎会导致问题盯着我的脸;)请帮助我了解我哪里出错了。
谢谢!
安德鲁
最佳答案
好的,我相信导致此问题的原因是您直接绑定(bind)到 String
.字符串为 不可变 在 C# 中,因此当您更改文本时,它无法更改 ObservableCollection
中的基础字符串.要解决这个问题,您可以简单地创建一个模型类来保存字符串数据,然后绑定(bind) 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;
}
}
请注意,我将您的依赖属性更改为标准属性 - 没有理由使集合成为依赖属性。除此之外,唯一的区别是包含了包装类
TestItem
保存字符串数据。<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>
现在
TextBox
绑定(bind)到 Name
TestItem
上的路径,并且此绑定(bind)按预期工作并修改集合。
关于wpf - 与 ItemsControl 的双向绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2785044/