绑定 ObservableCollection<>到一个文本框 [英] Binding ObservableCollection<> to a TextBox

查看:20
本文介绍了绑定 ObservableCollection<>到一个文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以 ObservableCollection 形式从 Web 服务返回的数据我想将集合绑定到只读 TextBox 以便用户可以选择并复制数据到剪贴板.

I have data comming back from web service in the form of a ObservableCollection<string> I want to bind the collection to a read-only TextBox so that the user can select and copy the data to the clipboard.

为了将集合绑定到 TextBox 的 Text 属性,我创建了 IValueConverter,它将集合转换为文本字符串.这似乎有效,只是它只有效一次,就好像绑定不识别 Observable 集合的后续更改.这是一个重现问题的简单应用程序,只是为了确认绑定工作正常,我还绑定到了一个ListBox"

To get the collection bound to the Text property of the TextBox I created IValueConverter which converts the collection to a text string. This seems to work except that it only works once, it is as if the binding does not recognize subsequent changes to the Observable collection. Here is a simple application that reproduces the problem, just to confirm the binding is working correctly I also bind to a `ListBox'

这是不是因为Text binding simple不处理集合的变化事件?

Is this because the Text binding simple does not handle the change events of the collection?

一个选项当然是让我处理集合更改并将这些更改传播到 TextBox 绑定到的 Text 属性,这很好,但我想了解为什么在我看来是一个明显的解决方案未按预期工作.

One option would of course be for me to handle the collection changes and propogate those to a Text property that the TextBox is bound to, which is fine, but I would like to understand why what seemed to me to be an obvious solutions is not working as expected.

XAML

<Window x:Class="WpfTextBoxBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfTextBoxBinding"
        Title="MainWindow" Height="331" Width="402">
  <StackPanel>
    <StackPanel.Resources>
      <local:EnumarableToTextConverter x:Key="EnumarableToTextConverter" />
    </StackPanel.Resources>
    <TextBox Text="{Binding TextLines, Mode=OneWay, Converter={StaticResource EnumarableToTextConverter}}" Height="100" />
    <ListBox ItemsSource="{Binding TextLines}" Height="100" />
    <Button Click="Button_Click" Content="Add Line" />
  </StackPanel >
</Window>

背后的代码

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Globalization;

namespace WpfTextBoxBinding
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    public ObservableCollection<string> TextLines {get;set;}

    public MainWindow()
    {
      DataContext = this;

      TextLines = new ObservableCollection<string>();

      // Add some initial data, this shows that the 
      // TextBox binding works the first time      
      TextLines.Add("First Line");

      InitializeComponent();      
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      TextLines.Add("Line :" + TextLines.Count);
    }
  }

  public class EnumarableToTextConverter : IValueConverter
  {
    public object Convert(
      object value, Type targetType, 
      object parameter, CultureInfo culture)
    {
      if (value is IEnumerable)
      {
        StringBuilder sb = new StringBuilder();
        foreach (var s in value as IEnumerable)
        {
          sb.AppendLine(s.ToString());
        }
        return sb.ToString();
      }
      return string.Empty;
    }

    public object ConvertBack(
      object value, Type targetType, 
      object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }
}

推荐答案

这是不是因为Text绑定simple 不处理变化集合的事件?

Is this because the Text binding simple does not handle the change events of the collection?

确实如此.绑定仅在其源属性发生变化时更新.如果您通过设置全新的 ObservableCollection 并实现 INotifyPropertyChanged 来更改 TextLines 属性,则您的绑定将按预期工作.仅当它绑定到诸如 ItemsControl.ItemsSource 之类的侦听集合更改的属性时,向集合中添加新元素才有意义.

Indeed. A binding updates only when its source property changes. If you change the TextLines property by setting a whole new ObservableCollection and implement INotifyPropertyChanged, your binding will work as expected. Adding new elements to the collection will have meaning only if it's bound to a property like ItemsControl.ItemsSource that listens to the collection changes.

一种选择当然适合我处理集合更改和将它们传播到 Text 属性TextBox 绑定到的,即很好.

One option would of course be for me to handle the collection changes and propogate those to a Text property that the TextBox is bound to, which is fine.

那将是另一种解决方案.

That would be another solution.

这篇关于绑定 ObservableCollection&lt;&gt;到一个文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆