Как добавить элемент в ListBox в WPF?

650
09 декабря 2016, 09:00

У меня не получается добавить элемент в ListBox по нажатию кнопки:

Класс элемента:

public class People
{
    public string FirstName {}
    public string LastName {}
}

Это лист:

private List<People> itemsList = new List<People>();
public List<People> ItemsList
{
    get { return itemsList; }
}

Команда для кнопки:

AddCommand = new Command(arg => AddMethod());
private void AddMethod()
{
    if (TextProperty1 == "" || TextProperty2 == "")
        {MessageBox.Show("Please write all fields"); return;}
    itemsList.Add(new People(TextProperty1, TextProperty2));
    OnPropertyChanged(nameof(ItemsList));
}

Код листбокса:

<ListBox  ItemsSource="{Binding ItemsList, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Stretch" Margin="5" 
          VerticalAlignment="Top" Height="300" Width="750" Grid.Row="1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid Margin="0,2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="100"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding LastName}"/>
                <TextBlock Text="{Binding FirstName}" Grid.Column="1"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Answer 1
    <ListBox  ItemsSource="{Binding ItemsList, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Stretch" Margin="5" 
              VerticalAlignment="Top" Height="300" Width="750" Grid.Row="1">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="0,2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="100"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding LastName}"/>
                    <TextBlock Text="{Binding FirstName}" Grid.Column="1"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
Answer 2

Используй вместо

List<People>
ObservableCollection<People>

Дело в том, что ObservableCollection при добавлении/удалении элементов кидает событие CollectionChanged, WPF умеет отслеживать данное событие и перерисовывать контрол.

В данном случае контрол не перерисовывается потому, что по факту у тебя источник бинднига не изменяется, т.е. ты добавляешь объект в коллекцию, но сама коллекция ссылается - это тот же самый объект, что и раньше, поэтому, несмотря на то, что ты делаешь OnPropertyChanged реально перерисовки не происходит.

Такой сценарий, как у тебя работал бы, если бы ты сделал так

private List<Person>_items = new List<Person>;
publc List<Person> Items
{
    get{ return new List<Person>(_items);}
}

В таком случае при обращении к Items всегда будет новый объект и контрол будет перерисовываться. Но все-таки удобнее использовать ObservableCollection.

READ ALSO
Асинхронное чтение из сокета (C#)

Асинхронное чтение из сокета (C#)

Необходимо асинхронно читать данные из сокета (NetworkStream) и выполнять действия в зависимости от считанных данныхВ бескрайних просторах интернета...

444
custom keyboard для telegram bot

custom keyboard для telegram bot

Я новичок в C# и что бы хоть не много попрактиковаться решил попробовать написать бота для телеграмаВсё бы ничего но у меня не получается создать...

470
Загрузить текущую сцену Unity

Загрузить текущую сцену Unity

Как загрузить текущую сцену Unity? Пробовал так

393
Unit Test UDP sender

Unit Test UDP sender

Как протестировать, написать unit test для UDP sender? Код:

353