获取从一个 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;
}
我正在处理我的第一个 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;
}