C# 如何在MainWindow中的StatusBarItem中更新WPF UserControl属性以形成另一个UserControl,两者都具有不同的数据上下文?
我试着寻找类似问题的答案,但我找不到任何适合这种情况的答案 我有一个类似这样的主窗口(省略了某些部分): 和两个用户控件:C# 如何在MainWindow中的StatusBarItem中更新WPF UserControl属性以形成另一个UserControl,两者都具有不同的数据上下文?,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我试着寻找类似问题的答案,但我找不到任何适合这种情况的答案 我有一个类似这样的主窗口(省略了某些部分): 和两个用户控件: <UserControl x:Class="test.Views.StatusView" xmlns:local="clr-namespace:test.Views" xmlns:ViewModels="clr-namespace:test.ViewModels"> <UserControl.DataContext>
<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都将自己的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() { }
}
}
以及:
正如您从代码配置文件中看到的,视图中有MouseEnter和MouseLeave事件,我想在StatusView中设置TextBlock.Text值(通过它的ViewModel.Status属性)
现在这里没有显示,但其他类也应该能够使用相同的原理,以线程安全的方式更新状态栏的值
我该如何做到这一点
我曾想过使用DependencyProperty或委托和事件,但不知道如何实现,因为目前,两个用户控件(和其他控件)都是通过MainWindow中的XAML实例化的,而不是通过代码隐藏。我认为,这就是应该怎么做的(如果我要遵循MVVM并将工作分离——设计师在设计,而程序员在编程),但这正是我不知道如何解决这个问题的原因
谢谢您的帮助。我强烈建议您使用MVVM Light 您可以使用MVVM Light Messenger。它是一个允许在对象之间交换消息的类。Messenger类主要用于在viewmodels之间发送消息: PS:我还建议使用命令绑定而不是事件处理程序(不像MVVM)
<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
}
}
}
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
}
}