C# WPF. ListBox не обновляется

563
26 декабря 2016, 22:37

Суть проблемы - ListBox внешне не обновляется при редактировании элемента...

Код ListBox'a:

<ListBox Name="ListBoxSyncItem" ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding Name}"/>
                        <Grid.ContextMenu>
                            <ContextMenu>
                                <MenuItem Header="Изменить" Click="MenuItem_Update_OnClick"></MenuItem>
                                <MenuItem Header="Удалить" Click="MenuItem_Delet_OnClick"></MenuItem>
                            </ContextMenu>
                        </Grid.ContextMenu>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

В окне в DataContext прописывается ObservableCollection

private readonly ObservableCollection<ListBoxItemSync> _listBoxItemSyncs = new ObservableCollection<ListBoxItemSync>();
...
public MainWindow()
        {
...
ListBoxSyncItem.DataContext = _listBoxItemSyncs;

Код ListBoxItemSync:

private class ListBoxItemSync
        {
            public string Name { get; set; }
            public SyncItem SyncItem { get; set; }
        }

Метод MenuItem_Update_OnClick (Вызывается через контекстное меню элемента ListBox'a):

private void MenuItem_Update_OnClick(object sender, RoutedEventArgs e)
    {
        var targetListItem = (ListBoxItemSync) ((MenuItem) sender).DataContext;
        var window = new CreateSyncItemWindow(targetListItem.SyncItem);
        //if (window.ShowDialog() == true)
        //{
        //  targetListItem.SyncItem = window.GetNewItem();
        //  targetListItem.Name = targetListItem.SyncItem.Name;
        //}
        if (window.ShowDialog() == true)
        {
            _listBoxItemSyncs.Remove(targetListItem);
            _listBoxItemSyncs.Add(new ListBoxItemSync() {SyncItem = window.GetNewItem(), Name = window.GetNewItem().Name });
        }
    }

В CreateSyncItemWindow создается новый элемент SyncItem, возвращается через метод GetNewItem.

В закомментированном куске кода нерабочий вариант. Он обновляет данные в коллекции _listBoxItemSyncs (ее элементы должен отображать ListBox), но внешний вид ListBox'a не меняется.

Второй вариант (тот что не закомментирован) удалит старый элемент из коллекции и добавит новый. Это обновит внешний вид ListBox'a, но данный метод мне не нравится тем, что "обновленный" элемент появится в любом случае в конце списка, а искать номер старого элемента перед его удаление... В общим кода будет много.

Как быть с 1 вариантом?

Answer 1

Проблема в том, что ваш класс ListBoxItemSync не реализует INotifyPropertyChanged. И таким образом ваши контролы не могут узнать, что содержимое поменялось.

Делайте так:

class ListBoxItemSync : INotifyPropertyChanged
{
    string name;
    public string Name
    {
        get { return name; }
        set { if (name != value) { name = value; NotifyPropertyChanged(); } }
    }
    SyncItem syncItem;
    public SyncItem SyncItem
    {
        get { return syncItem; }
        set { if (syncItem != value) { syncItem = value; NotifyPropertyChanged(); } }
    }
    void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}
READ ALSO
Семантика работы/хранения статики в CLR

Семантика работы/хранения статики в CLR

Известно, что статика не привязана к объекту (экземпляру), а хранится в типе объекта (!), и соответственна эта статика (в виде полей/методов...

385
Очередь заданий для объекта [требует правки]

Очередь заданий для объекта [требует правки]

вообщем есть объект, аккаунт в соц сети, есть методы, например постинг медиа, лайкинг фоловинг и тд как реализовать очередь заданий для это...

383
c# Как получить объект DataTable из BindingSource

c# Как получить объект DataTable из BindingSource

Как получить ссылку на DataTable из объекта BindingSource, если структура построена так:

551
Как правильно остановить Thread?

Как правильно остановить Thread?

Язык C#, Visual Studio 2013Скажите пожалуйста, как в консольном приложении обработать нажатия клавиши, чтобы остановить работающий Thread? Не могу найти...

330