Il tipo deve implementare INotifyPropertyChanged
in modo che una raccolta possa rilevare le modifiche. Come dice Sam, passare l'argomento string.Empty
.
È necessario che l'origine dati di ListBox
sia una raccolta che fornisce la notifica di modifica. Ciò avviene tramite l'interfaccia INotifyCollectionChanged
(o l'interfaccia non-così-WPF IBindingList
).
Ovviamente, è necessario attivare l'interfaccia INotifyCollectionChanged
ogni volta che uno degli elementi membri INotifyPropertyChanged
attiva l'evento. Per fortuna ci sono alcuni tipi nel framework che forniscono questa logica per te. Probabilmente il più adatto è ObservableCollection<T>
. Se si associa il ListBox
a un ObservableCollection<FooBar>
, la concatenazione dell'evento avverrà automaticamente.
Su una nota correlata, non è necessario utilizzare un metodo ToString
solo per ottenere WPF per eseguire il rendering dell'oggetto nel modo desiderato. È possibile utilizzare un DataTemplate
come questo:
<ListBox x:Name="listBox1">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:FooBar}">
<TextBlock Text="{Binding Path=Property}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
In questo modo è possibile controllare la presentazione dell'oggetto a cui appartiene - in XAML.
MODIFICA 1 Ho notato il tuo commento che stai utilizzando la raccolta ListBox.Items
come raccolta. Questo non farà il legame richiesto. È meglio fare qualcosa del tipo:
var collection = new ObservableCollection<FooBar>();
collection.Add(fooBar1);
_listBox.ItemsSource = collection;
Non ho controllato il codice per la precisione della compilazione, ma ottieni il succo.
MODIFICA 2 Utilizzando il numero DataTemplate
ho dato sopra (l'ho modificato per adattarlo al vostro codice) risolve il problema.
Sembra strano che l'attivazione di PropertyChanged
non causi l'aggiornamento dell'elenco, ma l'utilizzo del metodo ToString
non è il modo in cui WPF è stato progettato per funzionare.
Utilizzando questo DataTemplate, l'interfaccia utente si collega correttamente alla proprietà esatta.
Ho fatto una domanda su un po 'di tempo fa su string formatting in a WPF binding. Potresti trovarlo utile.
EDIT 3 Sono sconcertato sul motivo per cui questo non funziona ancora per voi. Ecco il codice sorgente completo per la finestra che sto usando.
codice dietro:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace StackOverflow.ListBoxBindingExample
{
public partial class Window1
{
private readonly FooBar _fooBar;
public Window1()
{
InitializeComponent();
_fooBar = new FooBar("Original value");
listBox1.ItemsSource = new ObservableCollection<FooBar> { _fooBar };
}
private void button1_Click(object sender, RoutedEventArgs e)
{
_fooBar.Property = "Changed value";
}
}
public sealed class FooBar : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string m_Property;
public FooBar(string initval)
{
m_Property = initval;
}
public string Property
{
get { return m_Property; }
set
{
m_Property = value;
OnPropertyChanged("Property");
}
}
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
XAML:
<Window x:Class="StackOverflow.ListBoxBindingExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackOverflow.ListBoxBindingExample"
Title="Window1" Height="300" Width="300">
<DockPanel LastChildFill="True">
<Button Click="button1_Click" DockPanel.Dock="Top">Click Me!</Button>
<ListBox x:Name="listBox1">
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:FooBar}">
<TextBlock Text="{Binding Path=Property}"/>
</DataTemplate>
</ListBox.Resources>
</ListBox>
</DockPanel>
</Window>
Ho aggiornato la mia risposta per mostrare come è possibile ottenere questo funzionamento. Sembra che DataTemplate sia la strada da percorrere. –