我正在尝试通过一个区域填充ItemsSource
a ComboBox
(的衍生物)。ItemsControl
看法
范围RegionManager
(在视图模型上找到)通过 分配给视图prism:RegionManager.RegionManager="{Binding RegionManager}"
。
主窗口.xaml
<Window x:Class="Applications.Testing.Wpf.RegionCreationTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Applications.Testing.Wpf.RegionCreationTester"
xmlns:prism="http://www.codeplex.com/prism"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
prism:RegionManager.RegionManager="{Binding RegionManager}"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid>
<ComboBox prism:RegionManager.RegionName="{x:Static local:RegionNames.itemsControlRegion}"/>
</Grid>
</Window>
主窗口.xaml.cs
namespace Applications.Testing.Wpf.RegionCreationTester
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, IModelled<MainWindowViewModel>
{
public MainWindowViewModel ViewModel
{
get
{
return (MainWindowViewModel)DataContext;
}
set
{
DataContext = value;
}
}
public MainWindow()
{
InitializeComponent();
ViewModel.PopulateItemsControl();
}
}
}
视图模型
视图模型通过 分配给视图的 DataContext prism:ViewModelLocator.AutoWireViewModel="True"
。
MainWindowViewModel.cs
namespace Applications.Testing.Wpf.RegionCreationTester
{
public class MainWindowViewModel
{
/// <summary>
/// Gets the <see cref="RegionManager"/> scoped to this control.
/// </summary>
/// <remarks>Exists so that child controls can register regions for their own child controls which are also child controls in this control.</remarks>
public RegionManager RegionManager { get; } = new RegionManager();
/// <summary>
/// Adds some child views to the <see cref="RegionNames.itemsControlRegion"/>.
/// </summary>
/// <remarks>Normally these views would be resolved using an IoC container but this have been omitted for brevity.</remarks>
public void PopulateItemsControl()
{
var region = RegionManager.Regions[RegionNames.itemsControlRegion];
region.Add(new TextBlock { Text = "Item #1" });
region.Add(new Button { Content = "Item #2" });
}
}
}
区域名称.cs
namespace Applications.Testing.Wpf.RegionCreationTester
{
public static class RegionNames
{
public const string itemsControlRegion = "collectionRegion";
}
}
引导程序
应用程序.xaml
<Application x:Class="Applications.Testing.Wpf.RegionCreationTester.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/>
应用程序.xaml.cs
namespace Applications.Testing.Wpf.RegionCreationTester
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new RegionCreationTesterBootstrapper().Run();
}
}
}
RegionCreationTesterBootstrapper.cs
namespace Applications.Testing.Wpf.RegionCreationTester
{
public class RegionCreationTesterBootstrapper : UnityBootstrapper
{
protected override DependencyObject CreateShell()
=> new MainWindow();
protected override void InitializeShell()
{
base.InitializeShell();
(Application.Current.MainWindow = (Window)Shell).Show();
}
}
}
一旦所有区域人口都发生并且应用程序即将运行,我会收到一个Prism.Regions.UpdateRegionsException
包含 InnerException 的消息,该消息"Region with the given name is already registered: collectionRegion"
位于App
. new RegionCreationTesterBootstrapper().Run()
我能够获得断点命中的代码中的最后一行是new MainWindow()
在CreateShell
调用 MainWindow 的构造函数退出之后的 in 。为什么我只尝试注册一次时却被告知该区域已经注册?我在 MainWindow 的构造函数中设置了断点,以确实确认它只创建一次,即使不是,RegionManager
它的作用域也应该防止发生此异常。我错过了什么?
更新
我刚刚注释掉了其中的代码PopulateItemsControl
,发现即使只有一个视图被添加到该区域并且仍然陌生,如果没有向该区域添加视图但该区域被访问(如行中所做的那样var region = RegionManager.Regions[RegionNames.itemsControlRegion];
:) . 因此,现在的问题与访问作用域 RegionManager 上的现有区域以进行视图注入有关,以便向其中添加视图;我不确定为什么从 RegionManager 访问一个区域会改变它的状态,这似乎是 Prism 中的一个错误,或者可能与惰性枚举有关。