Prism RequestNavigate和ViewModel OnPropertyChanged

时间:2013-11-26 10:51:21

标签: c# wpf mvvm telerik prism-4

我在WPF 4.5项目中使用Telerik RadRibbonView。设置看起来像这样。

在我的Shell中,我将RibbonView和TabControl定义为名为“RibbonRegion”和“TabRegion”的区域。 RibbonRegion基本上是应用程序的菜单,TabRegion包含主要内容。

我还创建了一个模块,其中包含一个包含RibbonTab和RibbonButton的View。此按钮用于设置RibbonContextTabView和TabItemView的DataContext并在各自的区域中注册它们的命令。 ContextTab和TabItem共享相同的ViewModel。此ViewModel具有ContextTab和TabItem绑定的属性“IsSelected”。

    if (_regionManager.Regions["RibbonRegion"].Views.Any(v => v.GetType() == typeof(ContextTabView)) && _regionManager.Regions["TabRegion"].Views.Any(v => v.GetType == typeof(TabItemView)))
    {
        _regionManager.RequestNavigate("RibbonRegion", new Uri("ContextTabView", UriKind.Relative));
        _regionManager.RequestNavigate("TabRegion", new Uri("TabItemView", UriKind.Relative));
    }
    else
    {
        ContextTabView contextTabView = _container.Resolve<ContextTabView>();
        TabItemView tabItemView = _container.Resolve<TabItemView>();
        contextTabView.DataContext = tabItemView.DataContext = new ContextTabTabItemViewModel();
        _regionManager.RegisterViewWithRegion("RibbonRegion", () => contextTabView);
        _regionManager.RegisterViewWithRegion("TabRegion", () => tabItemView);
    }

第一次执行上面的命令时,将设置视图的DataContext,然后在区域中注册它们。这也将“IsSelected”属性设置为true。如果我将焦点更改为RibbonTab,我的ContextTab和TabItem将失去焦点,并且“IsSelected”属性将设置为false。如果我再次按下按钮,则执行RequestNavigate,并再次将属性设置为true。这是我的问题。如果我这样做第三次没有任何反应!执行RequestNavigate但该属性未设置为true且视图未重新获得焦点。我对PRISM很新,我担心我离开这里。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

为了以松散耦合的方式保持 ViewModels 之间的通信,您只需使用 EventAggregator 并从命令按钮实现,然后由 TabItemViewModel 处理。

通过将一个 ViewModel 添加到另一个中而提到的解决方案并不理想,因为这些组件最终会使用紧耦合并定义不正确的情况 Views / ViewModels 不会依赖于另一个查看

因此,要完成 EventAgregation 方法,您需要从 View / ViewModel 上的容器throw构造函数接收 EventAggregator ,其中单击该按钮,在每个 ViewModels 上,您希望 订阅 到该事件设置 IsSelected EventHandler 方法中的 属性。

您可以订阅“ GiveFocusEvent ”事件并在 ViewModels 上处理它,这将设置 IsSelected 属性如下所示:

public TabItemViewModel(IEventAggregator eventAggregator, ..){
    ...
    GiveFocusEvent setFocusEvent = eventAggregator.Get<GiveFocusEvent>();
    setFocusEvent.Subscribe(SetFocusEventHandler, ThreadOption.UIThread);
}

public void SetFocusEventHandler(){
     // change IsSelected property value..
}

事件将从 按钮的CommandHandler 方法内发布,如下所示:

this.eventAggregator.GetEvent<GiveFocusEvent>().Publish();

请注意,您需要创建并使 GiveFocusEvent “事件类继承自 CompositePresentationEvent

public class GiveFocusEvent : CompositePresentationEvent<string>{}

我希望这能帮到你,

问候。