La liaison ObservableCollection<> à une zone de texte
J'ai des données venant de retour de service web sous la forme d'un ObservableCollection<string>
je veux lier la collection en lecture seule TextBox
de sorte que l'utilisateur peut sélectionner et copier les données dans le presse-papiers.
Pour obtenir la collection liée à la propriété Text de la zone de texte, j'ai créé IValueConverter
qui convertit la collecte d'une chaîne de texte. Cela semble fonctionner, sauf qu'il ne fonctionne qu'une fois, c'est comme si la liaison ne reconnaît pas les modifications ultérieures de la collection Observable. Voici une application simple qui reproduit le problème, juste pour confirmer la liaison fonctionne correctement j'ai aussi se lier à une "zone de liste'
Est-ce parce que le Texte de liaison simple ne permet pas de gérer les événements de changement de la collection?
Une option serait bien pour moi à gérer la collecte des changements et à propager ces à un Texte bien que la zone de texte est lié, ce qui est bien, mais j'aimerais comprendre pourquoi ce qui me semblait être une évidence solutions ne fonctionne pas comme prévu.
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 Derrière
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();
}
}
}
merci. J'espérais que les notifications de changement serait propogated à la zone de texte par le biais de la liaison.
OriginalL'auteur Chris Taylor | 2010-12-04
Vous devez vous connecter pour publier un commentaire.
En effet. Une liaison de mises à jour uniquement lorsque sa source propriété changements. Si vous modifiez le
TextLines
propriété en définissant une toute nouvelleObservableCollection
et de mettre en œuvreINotifyPropertyChanged
, votre liaison fonctionne comme prévu. L'ajout de nouveaux éléments à la collection n'a de sens que si elle est liée à une propriété commeItemsControl.ItemsSource
à l'écoute de la collection change.Qui serait une autre solution.
OriginalL'auteur Julien Lebosquain
Un peu plus élégante façon d'y parvenir est d'utiliser MultiBinding sur le Texte de la propriété et de se lier à la Collection du Comte de la propriété. Cela permettra de mettre à jour la liaison de tous les temps de la collection, qui compte les modifications et mettre à jour le Texte d'après un MultiValueConverter vous définissez.
Et le convertisseur:
Dans mon cas d'utilisation, je ne peux pas autoriser la zone de texte pour mettre à jour sa source (d'où le Mode="OneWay"), mais en cas de besoin du Convertisseur ConvertBack de la méthode de la poignée.
OriginalL'auteur Fueled
mise à jour de code ci-dessous
où txtName est votre nom de votre zone de texte
MVVM façon
1 - Difine une propriété de type chaîne de caractères dans votre Dernier comme indiqué ci-dessous et lier cette propriété à la zone de texte texte de propriété tel qu'illustré ci-dessous et supprimer ValueConverter pas besoin maintenant.
2 - je pense que vous avez très probablement de la manipulation de l'événement clic du bouton à l'aide d'un Gestionnaire de Commande de dire que votre Commande est AddMoreLines
donc dans le AddMoreLine Gestionnaire de Commande , après l'ajout d'un nouvel objet dans votre OBservrableCollection , créer un StringBuilder et ajouter tout le contenu de votre Collection et d'affecter la chaîne de la propriété créé à l'étape 1.
3 - Appel D'PropertyChanged Gestionnaire.
normalement je le fais d'une manière que je soulève un événement de ma vm et haendel sur mon point de vue c'est une sorte de hack et crée une liaison entre mon point de vue et ViewModel MAIS parfois ses pas posible de 100% complint avec MVVM et je peux vous dire un exemple classique, comme la gestion de DataGrid niveau de la cellule des opérations. MAIS dans votre cas il y a une possibilité de ne pas briser le MVVM , si vous voulez, je peux vous montrer comment le faire.
OriginalL'auteur TalentTuner