区域经理找不到自定义弹出窗口内部的区域



我使用带有Prism的弹出窗口的Interactivity对象的ShellView,以显示我的自定义设置视图。我的shellViewModel包含InteractionRequest对象和委托命令,该命令将启动用户交互。用户触发交互后,自定义设置视图(DataFeedManagerview)出现在ShellView的中心。在我的DataFeedManagerview中,左侧有一个dataFeeds(列表框控件)列表,并且右侧有DataFeed特定的设置视图(contentControl带有SET区域的ContentControl)。首先,我在RegisterViewWithRegion上注册了所有视图。那么我尝试做的是通过区域的激活方法激活相关对象设置在内容控制中。当我尝试这样做时,我会收到"找不到区域"的错误。因此,我们无法在自定义弹出窗口中使用区域?

ps1:也许这是如此简单的要求,但包含许多步骤,因为我的解释有点复杂。我希望代码将更具描述性。

ps2:我对使用简单的绑定到ContentControl的内容属性时达到了期望。但是我担心我的错误和/或正确的解决方案用于使用自定义交互弹出窗口中的区域。

.. :: shell :: ..

<Window x:Class="PrismUnityApp.Views.ShellView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:views="clr-namespace:PrismUnityApp.Views"
    xmlns:constants="clr-namespace:PrismUnityApp.Constants"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True"
    Title="{Binding Title}" Height="480" Width="640">
<DockPanel LastChildFill="True">
    <i:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <views:DataFeedManagerView/>
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>
    </i:Interaction.Triggers>
    <Button Content=" Show Data Feed Manager" Command="{Binding ShowDataFeedManagerCommand}"/>
    <ContentControl prism:RegionManager.RegionName="{x:Static constants:WellKnownRegionNames.ContentRegion}" />
</DockPanel>

using System.Windows.Input;
using Prism.Commands;
using Prism.Interactivity.InteractionRequest;
using Prism.Mvvm;
namespace PrismUnityApp.ViewModels
{
    public class ShellViewModel : BindableBase
    {
        private string _title = "Prism Unity Application";
        public ICommand ShowDataFeedManagerCommand { get; }
        public InteractionRequest<IConfirmation> ConfirmationRequest { get; }
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        public ShellViewModel()
        {
            ConfirmationRequest = new InteractionRequest<IConfirmation>();
            ShowDataFeedManagerCommand = new DelegateCommand(ShowDataFeedManager);
        }
        public void ShowDataFeedManager()
        {
            ConfirmationRequest.Raise(
                new Confirmation {Title = "Data Feed Manager", Content = string.Empty},
                confirmation =>
                {
                });
        }
    }
}

.. :: dataFeedManager :: ..

<UserControl x:Class="PrismUnityApp.Views.DataFeedManagerView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:constants="clr-namespace:PrismUnityApp.Constants"
         xmlns:prism="http://prismlibrary.com/"
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
         prism:ViewModelLocator.AutoWireViewModel="True"
         Height="240" Width="320">
<DockPanel LastChildFill="True">
    <ListBox
        SelectedItem="{Binding Current, Mode=OneWay}"
        ItemsSource="{Binding DataFeeds}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <prism:InvokeCommandAction
                    Command="{Binding SelectionChangedCommand}"
                    CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource Self}}"></prism:InvokeCommandAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Key}"></TextBlock>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <ContentControl prism:RegionManager.RegionName="{x:Static constants:WellKnownRegionNames.DataFeedRegion}"></ContentControl>
</DockPanel>

using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Unity;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using PrismUnityApp.Constants;
using PrismUnityApp.Interfaces;
namespace PrismUnityApp.ViewModels
{
    public class DataFeedManagerViewModel : BindableBase, IDataFeedManagerViewModel
    {
        private readonly IRegionManager _regionManager;
        public IDictionary<string, object> DataFeeds { get; }
        public ICommand SelectionChangedCommand { get; }
        public DataFeedManagerViewModel(IUnityContainer unityContainer, IRegionManager regionManager)
        {
            _regionManager = regionManager;
            SelectionChangedCommand = new DelegateCommand<SelectionChangedEventArgs>(SelectionChanged);
            DataFeeds = new Dictionary<string, object>
            {
                {WellKnownDataFeedNames.SimulationDataFeed, unityContainer.Resolve<ISimulationDataFeedView>()},
                {WellKnownDataFeedNames.BarchartDataFeed, unityContainer.Resolve<IBarchartDataFeedView>()}
            };
            foreach (var dataFeed in DataFeeds)
                _regionManager.RegisterViewWithRegion(WellKnownRegionNames.DataFeedRegion, () => dataFeed.Value);
        }
        public void SelectionChanged(SelectionChangedEventArgs e)
        {
            var addedItem = (KeyValuePair<string, object>) e.AddedItems[0];
            var region = _regionManager.Regions[WellKnownRegionNames.DataFeedRegion];
            region.Activate(addedItem.Value);
        }
    }
}

.. :: Bootstrapper :: ..

using System.Windows;
using Microsoft.Practices.Unity;
using Prism.Unity;
using PrismUnityApp.Interfaces;
using PrismUnityApp.ViewModels;
using PrismUnityApp.Views;
namespace PrismUnityApp
{
    class Bootstrapper : UnityBootstrapper
    {
        #region Overrides of UnityBootstrapper
        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
            Container.RegisterType<ISimulationDataFeedView, SimulationDataFeedView>();
            Container.RegisterType<ISimulationDataFeedViewModel, SimulationDataFeedViewModel>();
            Container.RegisterType<IBarchartDataFeedView, BarchartDataFeedView>();
            Container.RegisterType<IBarchartDataFeedViewModel, BarchartDataFeedViewModel>();
            Container.RegisterType<IDataFeedManagerView, DataFeedManagerView>();
            Container.RegisterType<IDataFeedManagerViewModel, DataFeedManagerViewModel>();
        }
        protected override DependencyObject CreateShell()
        {
            return Container.Resolve<ShellView>();
        }
        protected override void InitializeShell()
        {
            Application.Current.MainWindow.Show();
        }
        #endregion
    }
}

可能需要在弹出窗口的代码(构造函数)中手动设置区域管理器,如以下:

RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );

您必须为托管区域的内容控件分配一个名称,并以某种方式获取区域经理(ServiceLocator.Current.GetInstance<IRegionManager>())。

最新更新