Fengson
Fengson

Reputation: 4912

EASY way to refresh ListBox in WPF?

I have created a simple form that inserts/updates/deletes a values for Northwind Customers. Everything works fine, except in order to see a results, I have to close it, and reopen again. My form looks like this :

enter image description here

I've searched tens of articles on how to refresh ListBox, but all of those use interface implementing, or using DataSets, and stuff I have never heard of and cannot implement. It's a very simple project, using simple procedures. Is there an easy way to refresh the list of customers without adding many lines of code?

Upvotes: 9

Views: 42005

Answers (4)

Mike Yang
Mike Yang

Reputation: 2944

Use INotifyPropertyChanged is the best way, refresh the entire list is not a good idea.
Main entrance:

public partial class MainWindow : Window
{
    private BindingList<FoodModel> foodList = new BindingList<FoodModel>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        foodList.Add(new FoodModel { foodName = "apple1" });
        foodList.Add(new FoodModel { foodName = "apple2" });
        foodList.Add(new FoodModel { foodName = "apple3" });
        FoodListBox.ItemsSource = foodList;
    }

    private void Button2_Click(object sender, RoutedEventArgs e)
    {
        foodList[0].foodName = "orange";
    }

    private void RefreshButton_Click(object sender, RoutedEventArgs e)
    {
        FoodListBox.Items.Refresh();
    }
}

Model:

public class FoodModel: INotifyPropertyChanged
{
    private string _foodName;

    public string foodName
    {
        get { return _foodName; }
        set
        {
            if (_foodName != value)
            {
                _foodName = value;
                PropertyChanged(this, new PropertyChangedEventArgs("foodName"));
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}

XAML:

 <ListBox HorizontalAlignment="Center" Name="FoodListBox" VerticalAlignment="Top" Width="194" Height="150">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding foodName}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Upvotes: 0

zezba9000
zezba9000

Reputation: 3383

The simple answer is: myListBox.Items.Refresh();

Upvotes: 33

sa_ddam213
sa_ddam213

Reputation: 43616

Are you using ObservableCollection and does your model implement INotifyPropertyChanged these two things will automaticly update the ListBox on any change. no need to explicitly refresh the list.

Here is a small example of using ObservableCollection and INotifyPropertyChanged, obviously you will populate your ObservableCollection from your SQL database.

Window:

public partial class MainWindow : Window,  INotifyPropertyChanged
{
    private ObservableCollection<MyModel> _list = new ObservableCollection<MyModel>();
    private MyModel _selectedModel;

    public MainWindow()
    {
        InitializeComponent();
        List.Add(new MyModel { Name = "James", CompanyName = "StackOverflow"});
        List.Add(new MyModel { Name = "Adam", CompanyName = "StackOverflow" });
        List.Add(new MyModel { Name = "Chris", CompanyName = "StackOverflow" });
        List.Add(new MyModel { Name = "Steve", CompanyName = "StackOverflow" });
        List.Add(new MyModel { Name = "Brent", CompanyName = "StackOverflow" });
    }

    public ObservableCollection<MyModel> List 
    {
        get { return _list; }
        set { _list = value; }
    }

    public MyModel SelectedModel
    {
        get { return _selectedModel; }
        set { _selectedModel = value; NotifyPropertyChanged("SelectedModel"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

Xaml

<Window x:Class="WpfApplication11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Name="UI">
    <Grid>
        <ListBox ItemsSource="{Binding ElementName=UI, Path=List}" SelectedItem="{Binding ElementName=UI, Path=SelectedModel}" Margin="0,0,200,0" DisplayMemberPath="DisplayMember" SelectedIndex="0" />
        <StackPanel HorizontalAlignment="Left" Height="100" Margin="322,10,0,0" VerticalAlignment="Top" Width="185">
            <TextBlock Text="Name" />
            <TextBox Height="23" TextWrapping="Wrap" Text="{Binding ElementName=UI, Path=SelectedModel.Name, UpdateSourceTrigger=PropertyChanged}" />
            <TextBlock Text="Company Name" />
            <TextBox Height="23" TextWrapping="Wrap" Text="{Binding ElementName=UI, Path=SelectedModel.CompanyName, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </Grid>
</Window>

Model

public class MyModel : INotifyPropertyChanged
{
    private string _name;
    private string _companyName;

    public string Name
    {
        get { return _name; }
        set { _name = value; NotifyPropertyChanged("Name"); }
    }

    public string CompanyName
    {
        get { return _companyName; }
        set { _companyName = value; NotifyPropertyChanged("CompanyName"); }
    }

    public string DisplayMember
    {
        get { return string.Format("{0} ({1})", Name, CompanyName); }

    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
            PropertyChanged(this, new PropertyChangedEventArgs("DisplayMember"));
        }
    }
}

In this case any edit to properties will Update your list instantly, also will update when new Items are added/removed.

enter image description here

Upvotes: 13

user1610015
user1610015

Reputation: 6678

How about calling ListBox.UpdateLayout?

Of course you also need to update the particular item(s) so that it returns the updated string from the ToString method.

UPDATE: I think you also need to call ListBox.InvalidateArrange before you call ListBox.UpdateLayout.

Upvotes: 3

Related Questions