将ObservableCollection <double>绑定到ListBox而不更新源

时间:2016-03-08 16:35:34

标签: c# wpf xaml binding

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

截图

Example

我尝试了各种方法使用不同的绑定更新方法(显式,属性更改等),似乎没有任何区别。即使文本发生更改,绑定的DataItem和ResolvedSource也始终等于文本框的初始值。这可能与我使用原始数据类型有关吗?

我不认为我发布的示例会更新显示的值,因为double没有属性更改事件。我确实在ConvertBack转换器函数中放了一个断点,因为我至少期望在更改值时调用它,它应该反映在文本框中?或者这不是它的工作方式吗?

0 个答案:

没有答案