-1

我有一个问题,我将视图、视图模型创建编码到 ModuleInit.Initialize 方法中

this.container.RegisterType<IControlPanel, ViewModels.SeveritiesViewModel>("SeveritiesViewModel");
this.container.RegisterType<object, Views.SeveritiesView>("SeveritiesView", new InjectionConstructor(new ResolvedParameter<IControlPanel>("SeveritiesViewModel")));

SeveritiesVeiwModel 继承自 ViewModelBase

public class ViewModelBase : BindableBase, IControlPanel, INavigationAware, IConfirmNavigationRequest

ViewModelBase 的构造函数调用两个虚拟方法。初始化并获取数据。GetData 使用异步等待执行一些数据访问方法。

所以我遇到的问题是 Prism 构造了我的 SeveritiesViewModel,GetData 方法运行,并抛出了我捕获的异常。然后我想使用 InteractionRequest 显示一个对话框,但是尚未设置 view.DataContext,因此没有绑定或 Interaction.Triggers 来接收 InteractionRequest。

所以我想我应该使用回调来查看 RegionManager.RequestNaviagte。我想,由于我所有的视图模型都实现了 IConfirmNavigationRequest,所以我可以在注入的视图/视图模型的 NavigationResult 中返回 false。但是 ConfirmNavigationRequest 永远不会被调用。这是wpf不是silverlight吗?

那么我如何工作这个极其解耦的应用程序。我需要实现某种类型的共享服务吗?我想我将需要存储异常,直到视图完成与视图模型的绑定,也许使用检查异常集合的方法实现我自己的接口并在视图中调用接口方法?为什么从未调用 ConfirmNavigationRequest?

在设置 DataContext 之后,InteractionRequest 工作得很好,但之前;我不知所措。

任何建议将不胜感激。

谢谢加里

这是一些代码。

工具栏按钮命令单击运行以下。

this.regionManager.RequestNavigate("ContentRegion", "SeveritiesView");

这是视图背后的代码。

public partial class SeveritiesView : UserControl, IApplicationView
{
    public SeveritiesView(IControlPanel model)
    {
        InitializeComponent();
        this.DataContext = model;
    }

    public string ViewName
    {
        get { return "SeveritiesView"; }
    }
}

视图模型库。

        protected ViewModelBase(bool initializeDB = true) 
    {
        notifications = new List<NotificationWindowNotification>();
        this.uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
        NotificationRequest = new InteractionRequest<NotificationWindowNotification>();
        ConfirmationRequest = new InteractionRequest<ConfirmationWindowNotification>();
        if (initializeDB)
        {
            EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
            entityBuilder.ProviderConnectionString = EventLogAnalysis.Properties.Settings.Default.ConnectionString;
            db = new ServerEventLogEntities(entityBuilder.ToString());
        }
        ThrobberVisible = Visibility.Visible;
        Initialize();
        GetData();
    }

严重性视图模型。

 public SeveritiesViewModel(IRegionManager regionManager, IEventAggregator eventAggregator) : base()
    {
        try
        {
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;
            eventAggregator.GetEvent<AddSeverity>().Subscribe(AddSeverity);
            eventAggregator.GetEvent<DeleteSeverity>().Subscribe(DeleteSeverity);
        }
        catch(Exception e)
        {
                 uiFactory.StartNew(() =>
                NotificationRequest.Raise(new NotificationWindowNotification()
                {
                    Title = string.Format("Error during {0}.{1}"
                        , ModuleName, System.Reflection.MethodBase.GetCurrentMethod().Name),
                    Content = string.Format("{0}", e.Message)
                })
            ).Wait();
        }

    }

protected async override void GetData()
    {
        try
        {
            List<Task> tasks = new List<Task>();
            tasks.Add(GetEventFilterSeverities());

            await Task.WhenAll(tasks).ContinueWith((t) =>
            {
                ThrobberVisible = Visibility.Collapsed;
                eventAggregator.GetEvent<RecordStatusEvent>().Publish(new RecordStatusMessage() { CanAdd = true, CanDelete =(currentEventFilterSeverity != null), IsClosing = false });
            }
            , TaskScheduler.FromCurrentSynchronizationContext());
        }
        catch(Exception e)
        {
           notifications.Add(new NotificationWindowNotification()
                {
                    Title = string.Format("Error during {0}.{1}"
                        , ModuleName, System.Reflection.MethodBase.GetCurrentMethod().Name),
                    Content = string.Format("{0}", e.Message)
                });
        }

    }

protected async Task GetEventFilterSeverities()
    {
        try
        {
            throw new NullReferenceException("My exception");
            ObservableCollection<EventFilterSeverity> _eventFilterSeverities = new ObservableCollection<EventFilterSeverity>();
            var eventFilterSeverities = await (from sg in db.EventFilterSeverities
                                        orderby sg.EventFilterSeverityID
                                        select sg).ToListAsync();
            foreach (EventFilterSeverity efs in eventFilterSeverities)
                _eventFilterSeverities.Add(efs);
            EventFilterSeverities = _eventFilterSeverities;
        }
        catch(Exception e)
        {
            notifications.Add(new NotificationWindowNotification()
                {
                    Title = string.Format("Error during {0}.{1}"
                        , ModuleName, System.Reflection.MethodBase.GetCurrentMethod().Name),
                    Content = string.Format("{0}", e.Message)
                });
        }

    }
4

2 回答 2

0

两个相当简单的解决方案;

  1. 在显示 Shell 并且可以进行交互之前不要开始数据访问
  2. 捕获异常并在交互请求可用时立即await完成Task。这是导航完成的时候吗?这有效地将交互排队等待何时可以显示。
于 2015-10-01T14:56:56.040 回答
0

这看起来很有希望。在视图中

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Raised" SourceObject="{Binding NotificationRequest}">
        <i:EventTrigger.Actions>
            <dialogs:PopupWindowAction IsModal="True"/>
        </i:EventTrigger.Actions>
    </i:EventTrigger>
    <i:EventTrigger EventName="Loaded">
        <ei:CallMethodAction TargetObject="{Binding Mode=OneWay}" MethodName="DisplayPreBoundExceptions"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

在 ViewModelBase 中

        public void DisplayPreBoundExceptions()
    {
        notifications.ForEach((t) => NotificationRequest.Raise(t));
        notifications.Clear();
    }
于 2015-10-02T13:23:42.747 回答