获取属性从一个视图模型到另一个视图模型的已更改通知



我正在做我的第一个WPF项目。 我的 UI 需要更具交互性。我有 2 个视图模型。主窗口视图模型和世界视图模型。

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 code:

public class MainWindowViewModel : BaseViewModel
{
public WorldViewModel WorldViewModel { get; set; }
public bool IsWorldsComboEnabled => WorldViewModel.Worlds != null;
/// <summary>
/// Default constructor
/// </summary>
public MainWindowViewModel()
{
WorldViewModel = WorldViewModel.Instance;
}
}

世界观模型.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是一个类,它通过 NuGet 包提供 NotifyPropertyChangedPropertyChanged.Fody接口。

当"可观察集合"为空时Worlds必须禁用我的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;
}

最新更新