Bindung ObservableCollection<> an eine TextBox
Habe ich die Daten kommen wieder vom web service in form einer ObservableCollection<string>
ich binden wollen, die Sammlung zu einem nur-lese - TextBox
so dass der Benutzer auswählen kann, und kopieren Sie die Daten in die Zwischenablage.
Zu Holen Sie sich die Sammlung an die Text-Eigenschaft der TextBox, die ich erstellt IValueConverter
wandelt die Sammlung, um einen text-string. Dies scheint zu funktionieren, außer dass es nur einmal funktioniert hat, ist es, als wenn die Bindung nicht erkennen, nachträgliche änderungen am Observable-collection. Hier ist eine einfache Anwendung, die das problem reproduziert, nur um zu bestätigen, die Bindung richtig funktioniert habe ich auch eine Bindung zu einem `ListBox'
Ist dies, weil der Text verbindlich einfach nicht Griff die change-Ereignisse von der Sammlung?
Eine option wäre natürlich für mich zu handhaben, die Sammlung verpasst und propagieren diese in eine Text-Eigenschaft der TextBox gebunden ist, was in Ordnung ist, aber ich würde gerne verstehen, warum, was schien mir eine offensichtliche Lösungen nicht wie erwartet funktioniert.
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>
Code Hinter
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();
}
}
}
- Möglicherweise müssen Sie heben Sie eine Eigenschaft geändert-Ereignis für das Textfeld zu aktualisieren.
- danke. Ich hatte gehofft, dass die Benachrichtigungen ändern wäre propogated der TextBox durch die Bindung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In der Tat. Ein binding updates nur dann, wenn seine Quelle Eigenschaft änderungen. Wenn Sie ändern die
TextLines
Eigenschaft, durch die Einstellung eine ganz neueObservableCollection
und implementierenINotifyPropertyChanged
Ihr verbindliches, funktionieren wie erwartet. Hinzufügen neuer Elemente die Auflistung hat nur Sinn, wenn es gebunden ist, um eine Eigenschaft wieItemsControl.ItemsSource
hört sich die Auflistung ändert.Wäre eine andere Lösung.
Einen etwas eleganteren Weg das zu erreichen, ist die Verwendung MultiBinding auf die Text-Eigenschaft und die Bindung zu der Auflistung Count-Eigenschaft. Dies wird aktualisieren Sie die Bindung jedes mal die Auflistung Count-änderungen, und aktualisieren Sie den Text nach einem MultiValueConverter Sie definieren.
Dem Konverter:
In meinem Fall verwenden, ich glaube nicht das die TextBox Aktualisierung der Quelle (daher der Modus="OneWay"), aber wenn es sein muss der Wandler die Methode ConvertBack handhaben würden.
update code unten
wo txtName ist dein name deiner textbox
MVVM Weg
1 - Bestimmt eine Eigenschaft des Typs "string" in deinem ViewModel, wie gezeigt und binden Sie diese Eigenschaft, um die textbox text-Eigenschaft ein, die unten gezeigt und entfernen Sie ValueConverter keine Notwendigkeit jetzt.
2 - ich denke , Sie wahrscheinlich Umgang mit Schaltfläche click-Ereignis mithilfe von einen Command-Handler sagen, Ihr Befehl ist AddMoreLines
so, in der AddMoreLine Command-Handler , nach hinzufügen eines neuen Objekts in Ihrem OBservrableCollection , erstellen Sie ein StringBuilder-Objekt und append Sie alle Inhalte Ihrer Sammlung, und weisen Sie die Zeichenfolge für die Eigenschaft in Schritt 1 erstellt haben.
3 - Call PropertyChanged-Ereignishandler.