Как отключить изменение выбора ListView, когда элемент имеет изменения в MVVM/MVW?

У меня есть простая viewmodel:

private List<Item> itemsList;
public List<Item> ItemsList
{
    get { return itemsList; }
    set
    {
        itemsList= value;
        NotifyPropertyChanged();
    }
}

private Item selectedItem;
public Item SelectedItem
{
    get { return selectedItem; }
    set
    {
        selectedItem = value;
        NotifyPropertyChanged();
    }
}

// I call this method from button handler 
// window code behind: vm.SaveChanges()
// instead of RelayCommand because I'm lazy (I don't need strict MVVM)
public void SaveChanges() 
{
    context.SaveChanges();
}

Я считаю, что у меня есть ListView:

<ListView 
    ItemsSource="{Binding ItemsList}" 
    SelectedItem="{Binding SelectedItem}" 
/>

и несколько элементов управления со свойствами элемента:

<TextBox Text="{Binding SelectedItem.Name}"/>
<TextBox Text="{Binding SelectedItem.Phone}"/>

Когда я выбираю элемент в ListView - в поле TextBoxes появляются значения полей SelectedItem, я могу их редактировать и сохранять. Все работает нормально, но я не хочу позволять пользователю изменять выбранный элемент, прежде чем он сохранит изменения, потому что пользователь не увидит, что было изменено в другом элементе (ах).

Теперь я хочу отключить изменение выбора в ListView, когда элемент имеет несохраненные изменения.

Я экспериментировал со свойством ViewModel следующим образом:

public bool NoUnsavedChanges
{
    get { return !context.ChangeTracker.HasChanges(); }
    private set;
}

и связывание его со свойством IsEnabled объекта ListView, но, конечно, оно не работает, поскольку для этого свойства нет NotifyPropertyChanged().

Мой вопрос: как я могу отключить изменение выбора ListView (или отключить его полностью), когда выбранный элемент (или если есть несохраненные изменения во всем контексте)?

1 ответ

Решение

... и привязка его к свойству IsEnabled ListView, но, конечно, он не работает, потому что нет NotifyPropertyChanged() для этой собственности.

Поднять PropertyChanged событие тогда. Ваша модель представления должна реализовывать INotifyPropertyChanged событие и так должен ваш Item учебный класс. Если это не так, вы должны заменить его классом-оболочкой, который это делает. Вы могли бы затем поднять PropertyChanged событие для NoUnsavedChanges свойство модели представления всякий раз, когда состояние SelectedItem изменения, например:

private List<Item> itemsList;
public List<Item> ItemsList
{
    get { return itemsList; }
    set
    {
        itemsList = value;
        NotifyPropertyChanged();
    }
}

private Item selectedItem;
public Item SelectedItem
{
    get { return selectedItem; }
    set
    {
        if (selectedItem != null)
            selectedIten.PropertyChanged -= OnItemPropertyChanged;

        selectedItem = value;
        NotifyPropertyChanged();

        if (selectedItem != null)
            selectedIten.PropertyChanged += OnItemPropertyChanged;
    }
}

private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    NotifyPropertyChanged("NoUnsavedChanges");
}

public bool NoUnsavedChanges
{
    get { return !context.ChangeTracker.HasChanges(); }
}

public void SaveChanges()
{
    context.SaveChanges();
    NotifyPropertyChanged("NoUnsavedChanges");
}
Другие вопросы по тегам