9

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?

2
  • 2
    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 Commented Dec 31, 2012 at 1:39
  • 1
    Calling listBoxYourName.Items.Refresh() in all the places (add/remove) worked for me. Even though the collection is bound to ItemsSource. Weird but true story, folks. Commented Jun 4, 2014 at 22:11

4 Answers 4

34

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

Sign up to request clarification or add additional context in comments.

1 Comment

This is the answer for the question.
13

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

Comments

3

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.

5 Comments

which items do I need to update and how? Also, where do I put those lines? After Insert/Update/Delete methods?
Still, nothing changes.. :/
I think listbox itself has a refresh option. Like listbox1.refresh(), which does the same thing.
I mean the items you previously added to the listbox, which are presumably objects that override Object.ToString, aren't they?
you can try clearing the listbox and re-drawing from the database again also.
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.