MVVM/MVW 中的项目发生更改时如何禁用 ListView 选择更改?

How to disable ListView selection change when item has changes in MVVM/MVW?

我有简单的视图模型:

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}"/>

当我 select ListView 上的项目 - SelectedItem 字段值出现在 TextBox 中时,我可以编辑它们并保存它们。一切正常,但我不想让用户在保存更改之前更改 selected 项,因为用户将看不到其他项中的更改内容。

现在我想在项目有未保存的更改时禁用 selectListView 上的离子更改。

我正在像这样试验 ViewModel 属性:

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

绑定到ListView的IsEnabled属性,当然不行,因为这个属性.

没有NotifyPropertyChanged()

我的问题是:当 selected 项目(或者如果整个上下文中有未保存的更改)时,如何禁用 ListView selection 更改(或完全禁用它)?

...and binding it to IsEnabled property of ListView, but of course it does not work because there is no NotifyPropertyChanged() for this property.

然后引发 PropertyChanged 事件。您的视图模型应该实现 INotifyPropertyChanged 事件,您的 Item class 也应该如此。如果不是,您应该用可以的包装器 class 替换它。然后,只要 SelectedItem 的状态发生变化,您就可以为视图模型的 NoUnsavedChanges 属性 引发 PropertyChanged 事件,例如:

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");
}