Senff1389
Senff1389

Reputation: 13

WPF C# - How to dynamically add objects to ListView?

I have this assignment where I'm supposed to make a List (it HAS to be a List and not an Observable Collection for some reason) that collects the variables from four textboxes into one class and displays them in a Listview after a button is clicked.

When you type in new variables in the textboxes and press the button again, the ListView is supposed to display them in a row under the previous one.

That's where my problem comes in. Whenever I click the button, it only displays one row, and it is always the last 4 variables I entered. I did all the data bindings and stuff you're supposed to do with WPF, but it's still not working. You can check out my code below.

ListView definition in XAML

<ListView Name="lv" Grid.Column="1" Grid.Row="1" Grid.RowSpan="3" ItemsSource="{Binding}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Šifra" Width="35" DisplayMemberBinding="{Binding id}" />
                <GridViewColumn Header="Naziv" Width="70" DisplayMemberBinding="{Binding n}" />
                <GridViewColumn Header="Geo. širina" Width="67" DisplayMemberBinding="{Binding s}" />
                <GridViewColumn Header="Geo. dužina" Width="67" DisplayMemberBinding="{Binding d}" />
            </GridView>
        </ListView.View>
    </ListView>

Program that's executed when you click the button in XAML.CSe

private void Button_Click(object sender, RoutedEventArgs e)
    {
       
        bool x;
        string naz,temp=sifra.Text;
        int sif;
        List<Lokalitet> items = new List<Lokalitet>();
        float sir, duz;
        x = Int32.TryParse(temp,out sif);
        if(x==true)
        {
            temp = sirina.Text;
            temp = temp.Replace(',', '.');
            x = float.TryParse(temp, out sir);
            if(x==true)
                {
                temp = duzina.Text;
                temp = temp.Replace(',', '.');
                x = float.TryParse(temp, out duz);
                if (x == true)
                    {
                        naz = naziv.Text;
                        items.Add(new Lokalitet() { id = sif, s = sir, d = duz, n = naz });
                        lv.ItemsSource = items;
                }
                else MessageBox.Show("Nije unet realan broj geografske dužine");
                }
            else MessageBox.Show("Nije unet realan broj geografske širine");
        }
        else MessageBox.Show("Nije unet ceo broj koji označava šifru");

    }

Class Lokalitet definition

class Lokalitet
{
    public int id { get; set; }
    public  float s { get; set; }
    public float d { get; set; }
    public string n { get; set; }
}

I hope this is not written too messy, I hope it's not that big of a problem that all the variables and Alert messages are written in Serbian, it was a lot easier for me to know which is which that way.

Upvotes: 0

Views: 853

Answers (1)

Michael
Michael

Reputation: 1096

First of all, you are recreating your items list every time the button is clicked - so it always have only one item. Move List<Lokalitet> items = new List<Lokalitet>(); to window class property.

public partial class MainWindow : Window
{

    public List<Lokalitet> LocItems { get; set; } = new List<Lokalitet>();
}

Also your ItemsSource is not updated because it checks that you are assigning the same collection. It will update if you will assign null before reassigning the collection:

lv.ItemsSource = null;
lv.ItemsSource = LocItems;

Also you don't need Binding in XAML if you are assigning ItemsSource property directly.

I strongly discourage you to use this double assignment hack because:

  1. It's wrong and hard to understand
  2. It may cause performance issues.

It's better to discuss and use ObservableCollection.

Upvotes: 1

Related Questions