Mvvm prism:如何将shell.xaml中的内容绑定到区域内容变量?
应用程序位于prism/mvvm/mef中,并使用StockTraderRI等属性加载 My shell窗口包含状态栏的DockPanel,它是shell的全局,而不是每个区域的局部 看起来像这样:Mvvm prism:如何将shell.xaml中的内容绑定到区域内容变量?,mvvm,binding,prism,Mvvm,Binding,Prism,应用程序位于prism/mvvm/mef中,并使用StockTraderRI等属性加载 My shell窗口包含状态栏的DockPanel,它是shell的全局,而不是每个区域的局部 看起来像这样: <DockPanel> <StatusBar DockPanel.Dock="Bottom"> <StatusBarItem> <TextBlock Text="{Binding Source={x:Static bcl:Config
<DockPanel>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Text="{Binding Source={x:Static bcl:Configuration.Global}, Path=LoggedOn.User}"/>
</StatusBarItem>
<StatusBarItem>
<TextBlock Text="{Binding StateMessage}"/>
</StatusBarItem>
</StatusBar>
<ContentControl x:Name="MainContent" cal:RegionManager.RegionName="MainRegion"/>
</DockPanel>
绑定到全局变量确实很有效。现在,我想将StatusBarItem中的StateMessage绑定到加载到MainRegion的任何控件中的属性StateMessage。我的第一个猜测是使用如下内容:
<TextBlock Text="{Binding Path=DataContext.StateMessage,Source={StaticResource MainContent}}"/>
但这当然不起作用,因为MainContent不是静态资源
有人能告诉我一种将文本属性绑定到加载到MainRegion中的UserControl的某些属性的方法吗?我认为您无法找到一种直接绑定到区域中对象的属性的干净方法。实现这一点的一种方法是让指定区域中的所有视图从公共接口继承,以便它们都实现相同的属性(例如,SystemName)。您可以绑定到包含该属性的路径,并使用ValueConverter将类型从System.Object更改为接口类型 我的问题是,它限制了您可以在区域中输入的内容,并且似乎将shell与其中显示的类型耦合起来,这超出了我个人的意愿。我建议采用另一种方法:因为状态栏是shell的一部分,所以为shell提供一个ViewModel,其中包含状态栏绑定到的属性,并使用事件跟踪状态值何时更改。这样做有几个好处:
// Use normal binding for Shell -> ShellViewModel
public sealed ShellViewModel : INotifyPropertyChanged
{
private readonly IEventAggregator = eventAggregator;
public ShellViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
_eventAggregator.GetEvent<MainRegionViewLoaded>.Subscribe(
new Action<Object>(HandleMainRegionViewLoaded));
}
private String _statusName;
public String StatusName
{
get { return _statusName; }
set
{
if (_statusName != value)
{
_statusName = value;
RaisePropertyChanged("StatusName"); // Not showing this...
}
}
}
private void HandleMainRegionViewLoaded(Object param)
{
// Not doing all the checking here, such as null, etc.
var statusName = param as String;
StatusName = statusName;
}
}
//对Shell->ShellViewModel使用普通绑定
公共密封ShellViewModel:INotifyPropertyChanged
{
私有只读IEventAggregator=eventAggregator;
公共ShellViewModel(IEventAggregator事件聚合器)
{
_eventAggregator=eventAggregator;
_eventAggregator.GetEvent.Subscribe(
新操作(HandleMainRegionViewLoaded);
}
私有字符串_statusName;
公共字符串状态名
{
获取{return\u statusName;}
设置
{
如果(_statusName!=值)
{
_statusName=值;
RaisePropertyChanged(“StatusName”);//不显示此。。。
}
}
}
私有void HandleMainRegionViewLoaded(对象参数)
{
//没有在这里执行所有检查,例如null等。
var statusName=param作为字符串;
StatusName=StatusName;
}
}
现在,您的视图所要做的就是实现IActiveAware,并在激活时引发事件。或者,您可以让视图的ViewModel执行此操作(这可能更好,但需要一些额外的通信。对此有一些解释)
public void主视图:用户控件,IActiveAware
{
私有只读ieventagegrator\u事件聚合器;
公共主视图(IEventAggregator事件聚合器)
{
初始化组件();
_eventAggregator=eventAggregator;
}
私人楼宇是活跃的;
公共福利活动
{
获取{return\u isActive;}
设置
{
如果(值)
{
_eventAggregator.GetEvent.Publish(新的MainRegionViewLoaded(“我的名字”);
}
_i活跃=价值;
}
}
}
public void MainView : UserControl, IActiveAware
{
private readonly IEventAggregator _eventAggregator;
public MainView(IEventAggregator eventAggregator)
{
InitializeComponent();
_eventAggregator = eventAggregator;
}
private bool _isActive;
public bool IsActive
{
get { return _isActive; }
set
{
if (value)
{
_eventAggregator.GetEvent<MainRegionViewLoaded>.Publish(new MainRegionViewLoaded("My Name"));
}
_isActive = value;
}
}
}