Jonathan Wood
Jonathan Wood

Reputation: 67223

Update bound control

I'm learning WPF. I figured out how to bind to a list box using the following code.

XAML

<ListBox Name="lstUpdates" Grid.Row="1" Grid.Column="0" Margin="5,0,5,5" ItemsSource="{Binding HistoryData}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Loaded="lstUpdates_Loaded">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel >
                <TextBlock Text="{Binding Header}" FontWeight="Bold" />
                <TextBlock Text="{Binding Description}" TextWrapping="Wrap" Height="46" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

CS

public class HistoryRow
{
    public string Header { get; set; }
    public string Description { get; set; }
    public int ArticleUpdateId { get; set; }
}

public IEnumerable<HistoryRow> HistoryData { get; set; }

DataContext = this;
HistoryData = new List<HistoryRow>
{
    new HistoryRow { Header = "10/29/1961", Description = "Blah blah" },
    new HistoryRow { Header = "12/2/1976", Description = "Blah blah" },
    new HistoryRow { Header = "5/24/1992", Description = "Blah blah" },
    new HistoryRow { Header = "2/18/2012", Description = "Blah blah" },
};

I've got this so it works pretty well. But now my question is how can I refresh my listbox when my data changes. I've found several "solutions" on the Web and none of them work for me.

Upvotes: 1

Views: 55

Answers (3)

Jonathan Wood
Jonathan Wood

Reputation: 67223

My solution: Don't use binding. Just populate the list by creating a collection and assigning it to the ItemsSource property. Then, when the data has changed, do it again.

I don't know why WPF has to make so many things a pain, but when it's difficult to get a clear answer on stackoverflow on how to refresh the list, or I'm looking into reading a bunch of articles for such a simple task, it's probably a good indication I'm on the wrong track.

Perhaps I will find a reason to get into MVVM design and binding. But for now, all I want to do is update my ListBox.

Upvotes: -2

Fabio
Fabio

Reputation: 32455

You need to inform a view about changes of your collection.
When using ObservableCollection as source of ListBox control, the view listening a event CollectionChanges and update control when event get raised.

So change type of HistoryData to ObservableCollection<YourHistoryDataType>

To work properly you need keep same instance of collection and update only items.

To keep same instance create a property on your viewmodel:

private ObservableCollection<HistoryRow> _HistoryData;

public ObservableCollection<HistoryRow> HistoryData 
{ 
    get 
    {
        return _HistoryData;
    }
    set 
    {
         If(Equals(_HistoryData, value) return;
        _HistoryData = value; 
        this.OnPropertyChange(nameof(this.HistoryData);
    }
}  

Calling OnPropertyChanged will inform view about that instance of collection was changed.

Read this: Implementing the Model-View-ViewModel Pattern
There are some information about ObservableCollection and PropertyChanged event

Upvotes: 2

Master
Master

Reputation: 2153

Your class HistoryRow will need to extend INotifyOfPropertyChange,

Then instead of using an Ienumerable, it needs to be of type ObservableCollection and subscribe to PropertyChangeEvent

private ObservableCollection<HistoryRow> _historyData;
public ObservableCollection<HistoryRow> HistoryData 
{ 
    get {return _historyData}
    set {_historyData = value; OnPropertyChange("HistoryData");}
}

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));
    }
}

Upvotes: 1

Related Questions