获取从一个 ViewModel 到另一个 ViewModel 的 PropertyChanged 通知

Get PropertyChanged notification from one ViewModel to another

我正在处理我的第一个 WPF 项目。 我的 UI 需要更具互动性。我有 2 个视图模型。 MainWindowViewModel 和 WorldViewModel。

MainWindow xaml 简化代码:

<Window>
    [...]
    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <!--Worlds combobox-->
        <ComboBox Margin="2 0 0 0" MinWidth="100" IsEnabled="{Binding IsWorldsComboEnabled}"
        ItemsSource="{Binding WorldViewModel.Worlds}" SelectedValue="{Binding WorldViewModel.CurrentWorld}"
        DisplayMemberPath="Name"/>
    </Grid>
</Window>

MainWindowViewModel.cs代码:

public class MainWindowViewModel : BaseViewModel
{
    public WorldViewModel WorldViewModel { get; set; }

    public bool IsWorldsComboEnabled => WorldViewModel.Worlds != null;

    /// <summary>
    /// Default constructor
    /// </summary>
    public MainWindowViewModel()
    {
        WorldViewModel = WorldViewModel.Instance;
    }
}

WorldViewModel.cs代码:

public class WorldViewModel : BaseViewModel
{
    public ObservableCollection<World> Worlds { get; set; }

    public World CurrentWorld { get; set; }

    public static WorldViewModel Instance { get; set; }

    // Called on startup
    public static void Initialize()
    {
        Instance = new WorldViewModel();
    }

    /// <summary>
    /// Default constructor
    /// </summary>
    public WorldViewModel()
    {

    }
}

ViewModels 有点大,但这是最少需要的代码。 BaseViewModel 是一个 class,它提供带有 PropertyChanged.Fody NuGet 包的 NotifyPropertyChanged 接口。

Worlds ObservableCollection 为空时,必须禁用我的 ComboBox。当 IsWorldsComboEnabled 位于 WorldViewModel 时,它工作得很好,但我觉得这不是一个可行的方法。多个视图将取决于 WorldViewModel,但它们不需要 IsWorldsComboEnabled 属性。所以它的位置是 MainWindowViewModel.

WorldViewModel 中的 属性 发生变化时,有什么方法可以通知 MainWindowViewModel 吗?

下面这行代码的问题在于,即使WorldViewModel.Worlds改变了,IsWorldsComboEnabled的setter也不会被执行,所以你的PropertyChangedEventHandler不会被执行打电话。

public bool IsWorldsComboEnabled => WorldViewModel.Worlds != null

你可以改成public bool IsWorldsComboEnabled { get; set; } 并评估以下表达式

IsWorldsComboEnabled = WorldViewModel.Worlds != null;

每当您更改 属性 WorldViewModel.Worlds。

在您的情况下,属性 是 ObservableCollection,您可以注册 CollectionChanged 事件

WorldViewModel.Worlds.CollectionChanged += MyCollectionChangedMethod;

并计算那里的表达式

private void MyCollectionChangedMethod(object sender, NotifyCollectionChangedEventArgs e)
{
  IsWorldsComboEnabled = WorldViewModel.Worlds != null;
}