我尝试搜索类似问题的答案,但找不到适合这种情况的答案。
我有一个看起来像这样的主窗口(有些部分被省略):
<Window x:Class="test.MainWindow"
xmlns:local="clr-namespace:test"
xmlns:Views="clr-namespace:test.Views">
<Grid>
<DockPanel>
<StatusBar>
<StatusBarItem>
<Views:ProfileView />
</StatusBarItem>
<Separator />
<StatusBarItem>
<Views:StatusView />
</StatusBarItem>
</StatusBar>
</DockPanel>
</Grid>
</Window>
代码隐藏:
using System.Windows;
namespace test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// some stuff done here
}
}
和两个用户控件:
<UserControl x:Class="test.Views.StatusView"
xmlns:local="clr-namespace:test.Views"
xmlns:ViewModels="clr-namespace:test.ViewModels">
<UserControl.DataContext>
<ViewModels:StatusViewModel/>
</UserControl.DataContext>
<Grid>
<Border>
<TextBlock Text="{Binding Status}" />
</Border>
</Grid>
</UserControl>
和:
<UserControl x:Class="test.Views.ProfileView"
xmlns:local="clr-namespace:test.Views"
xmlns:ViewModels="clr-namespace:test.ViewModels" MouseEnter="UserControl_MouseEnter" MouseLeave="UserControl_MouseLeave">
<UserControl.DataContext>
<ViewModels:ProfileViewModel/>
</UserControl.DataContext>
<Grid>
// some stuff done here
</Grid>
</UserControl>
代码隐藏:
using System.Windows.Controls;
namespace test.Views
{
public partial class StatusView : UserControl
{
public StatusView()
{
InitializeComponent();
}
}
}
和:
using System.Windows.Controls;
namespace test.Views
{
public partial class ProfileView : UserControl
{
public ProfileView()
{
InitializeComponent();
}
private void UserControl_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
// Update status bar text
}
private void UserControl_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
// Update status bar text
}
}
}
每个 UserControl 都有自己的 ViewModel 设置为 DataContext:
using System;
using System.ComponentModel;
namespace test.ViewModels
{
class StatusViewModel : INotifyPropertyChanged
{
private string _status = string.Empty;
public string Status
{
get { return _status; }
set { _status = value; OnPropertyChanged("Status"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public StatusViewModel() { }
}
}
和:
using System;
namespace test.ViewModels
{
class ProfileViewModel
public ProfileViewModel() { }
// some stuff done here
}
}
正如您从代码中看到的那样,ProfileView 具有 MouseEnter 和 MouseLeave 事件,我想在这些事件上设置 StatusView 中的 TextBlock.Text 值(通过它的 ViewModel.Status 属性)。
此处未显示,但其他类也应该能够使用相同的原理以线程安全的方式更新状态栏的值。
我如何实现这一目标?
我想过使用 DependencyPropertyes 或 Delegates and Events,但不知道该怎么做,因为目前,UserControl(和其他)都是通过 MainWindow 中的 XAML 实例化的,而不是通过代码隐藏。我认为这就是应该这样做的方式(如果我要遵循 MVVM 并且有工作分离 - 设计师在设计而程序员在编程)但是,这正是我不知道如何解决这个问题的原因.
感谢您的帮助。
最佳答案
我强烈推荐使用 MVVM Light。
您可以使用 MVVM Light Messenger。它是一个允许在对象之间交换消息的类。 Messenger 类主要用于在 View 模型之间发送消息: http://dotnetpattern.com/mvvm-light-messenger
PS:我还建议使用命令绑定(bind)而不是事件处理程序(这不像 MVVM)。
关于c# - 如何更新 MainWindow 中 StatusBarItem 中的 WPF UserControl 属性形成另一个具有不同 DataContexts 的 UserControl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40785277/