我有ListBox
绑定到ObservableCollection<double>
。在这个ListBox中,我定义了自己的模板,它只有一些文本和一个用于修改值的文本框。目标是用户可以键入第二个文本框以更新“值”列表中的第二个值。但是,即使使用TwoWay模式,这似乎也不会更新源。我很难过。这是最好的方法,还是我做的工作是我不需要做的?我在示例项目中重新创建了这个问题,这里是代码:
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DoubleToStringConverter x:Key="DoubleToStringConv" />
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Path=Values}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Height" Padding="0"/>
<TextBox Margin="20 0 0 0" Width="50" Text="{Binding Path=., Converter={StaticResource DoubleToStringConv}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" KeyDown="TextBox_KeyDown" />
<Label Content=" and the value is" Padding="0" />
<TextBlock Margin="20 0 0 0" Width="50" Text="{Binding Path=., Converter={StaticResource DoubleToStringConv}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
代码
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
private ObservableCollection<double> _values = new ObservableCollection<double>();
public ObservableCollection<double> Values
{
get { return _values; }
set
{
_values = value;
OnPropertyChanged("Values");
}
}
public MainWindow()
{
DataContext = this;
InitializeComponent();
Values.Add(10);
Values.Add(10);
Values.Add(10);
}
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
TextBox box = sender as TextBox;
if (sender is TextBox)
{
if (e.Key == Key.Enter)
{
BindingExpression exp = box.GetBindingExpression(TextBox.TextProperty);
exp.UpdateSource();
}
}
}
}
public class DoubleToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return value.ToString();
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
double val = 0;
double.TryParse(value.ToString(), out val);
return val;
}
}
}
截图
我尝试了各种方法使用不同的绑定更新方法(显式,属性更改等),似乎没有任何区别。即使文本发生更改,绑定的DataItem和ResolvedSource也始终等于文本框的初始值。这可能与我使用原始数据类型有关吗?
我不认为我发布的示例会更新显示的值,因为double
没有属性更改事件。我确实在ConvertBack
转换器函数中放了一个断点,因为我至少期望在更改值时调用它,它应该反映在文本框中?或者这不是它的工作方式吗?