【问题标题】:Adding View to RegionManager in C# Module Does Not Work在 C# 模块中向 RegionManager 添加视图不起作用
【发布时间】:2014-02-11 16:08:36
【问题描述】:

我正在将 VB.NET PRISM 模块转换为 C#。这是一个非常简单的事情,目前在 VB.NET 中工作。它显示一个绑定到 ViewModel 的字符串值。

视图的 XAML(我将其切换为硬编码文本以强制其显示,通常它是一个数据绑定控件):

<UserControl x:Class="StatusBarAlarmsView"
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                     mc:Ignorable="d" 
                     MinWidth="150">
    <Grid>
        <TextBlock Text="Garrison" VerticalAlignment="Center"/>
    </Grid>
</UserControl>

以下代码在 VB 中用于显示视图:

regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, 
    Function() container.Resolve(Of iSBAlarmsPresenter).view)

我尝试用转换后的 C# 代码做同样的事情,它看起来像这样:

this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion,
    () => new StatusBarAlarmsView());

我已经尝试了上述 C# 的多种排列,但都没有成功:

// One
var statusbarRegion = regionManager.Regions[RegionNames.statusBarRegion];
var test = new StatusBarAlarmsView();
test.ViewModel = new AlarmViewModel(this.logger, this.eventAggregator, null, 
    this.container);
statusbarRegion.Add(test);

// Two
this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion,
    () => container.Resolve<iSBAlarmsPresenter>().View);

我不会详细介绍 View 和 ViewModel 是如何连接的,因为目前我并不关心这一点——我只是希望它显示“Garrison”。

其他信息 使用 Snoop,我可以深入到 StatusBar 区域。我可以看到该区域中显示的其他项目,并且它们都按预期设置了 DataContexts。

然而,对于我的警报模块,ContentPresenter 没有继承的 DataContext,它被标记为 Local,这与该区域中的所有其他项目不同。当我尝试查看最底部 ContentPresenter 的 DataContext 时,我被告知“对象为 NULL”。

不过,所有这些都不是重点,因为我的视图正在加载到树中,但我的 TextBlock 没有显示。

更新 根据要求,StatusBar 区域的 XAML 标记:

<Grid Name="StatusBarGrid" Grid.Row="3" Height="30">
    <e:Interaction.Behaviors>
        <behaviors:GridHeightModifyOnFontChangeBehavior FontSize="{DynamicResource AppFontSize}"/>
    </e:Interaction.Behaviors>
    <DockPanel >
        <WrapPanel  DockPanel.Dock="Right"  cal:RegionManager.RegionName="{x:Static inf:RegionNames.statusBarRightRegion}" Orientation="Horizontal" Background="{DynamicResource ControlBackgroundBrush}"   />
        <StatusBar DockPanel.Dock="Left"  cal:RegionManager.RegionName="{x:Static inf:RegionNames.statusBarRegion}" />
    </DockPanel>
</Grid>

【问题讨论】:

  • "使用 Snoop 的附加信息,我可以深入到 StatusBar 区域。我可以看到该区域中显示的其他项目,并且它们的 DataContexts 都按预期设置。"您是否在该区域注册了超过 1 个视图?如果是这样,在您进行导航之前,只有注册的第一个视图是可见的。如果没有,发布您创建区域的位置的 XAML 会有所帮助。
  • @TTat 我已经用区域标记更新了帖子的底部。此状态栏区域显示 5 个不同的视图,所有视图并排显示在应用程序窗口的底部。
  • 只是澄清一下。你在做这样的事情? this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, () => new StatusView1()); this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, () => new StatusView2()); ... this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, () => new StatusBarAlarmsView());
  • StatusBarRegion 中显示的每个模块在初始化期间都会向 RegionManager 注册它们的视图,因此代码不会同时运行,但是是的,它实际上与此类似。
  • 对不起,如果这是一个愚蠢的问题,但我需要问:你是在 StatusBarAlarmsView 的构造函数中调用 InitializeComponent 方法吗?

标签: .net wpf mvvm prism


【解决方案1】:

我认为您正试图在您的状态区域中同时显示所有 5 个状态视图?那是不可能的。在区域中注册的第一个视图将可见并处于活动状态。在您导航到它之前,您注册的其他人不会显示。

在加载完所有内容后尝试在某处执行此操作,以查看您的 StatusBarAlarmsView 是否显示。

this.regionManager.RequestNavigate(RegionNames.statusBarRegion, new Uri("StatusBarAlarmsView", UriKind.Relative));

还可以让容器为您创建视图,以便它可以处理视图模型和所有依赖项:

this.regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, typeof(StatusBarAlarmsView));

【讨论】:

  • 每个视图显示不同的东西,并且是它自己的视图/VM 和模块。它们目前都在 StatusBar 控件中一起工作和显示。此模块/代码在 VB 中工作,并按预期显示。在 C# 中使用相同的代码时它不起作用。
  • 可以,但每个区域一次只能显示 1 个视图。您正在尝试将 5 个不同的视图注册到您的 RegionNames.statusBarRegion 中,对吗?只有第一个注册的将可见。之后的任何内容都已注册,但在您“导航”到该视图之前不会处于活动状态。
  • 我检查了所有模块都调用了相同的代码:regionManager.RegisterViewWithRegion(RegionNames.statusBarRegion, Function() container.Resolve(Of IxxxPresenter).view)。每个模块都有自己的 Presenter 接口和实现,它们都有不同的 View/VM 实现。他们之间没有任何共享。它们都同时显示。该代码也没有单个 RequestNavigate() 调用。
  • 如果您在应用程序中加载多个模块并且他们都试图将视图注册到“StatusBarRegion”中,则只会显示注册的第一个视图,直到您导航到其中一个其他意见。将视图注册到该区域就像在该区域放置一张卡片一样。每次注册另一个视图时,它都会将其放在堆栈的底部。当您“导航”时,您选择了您想要查看的“卡片”并将其放在顶部。
  • 我不想自相矛盾,但事实似乎并非如此。想象一下在一个地基上铺设了 5 块砖,而这正是这些视图在一个区域中的显示方式。这是我正在尝试将其转换为 C# 的工作代码、工作模块。这不是我要开始工作的代码。感谢您的帮助!
【解决方案2】:

你是在StatusBarAlarmsView的构造函数中调用InitializeComponent方法吗?

添加视图时的一个常见错误(特别是如果您需要修改这些视图的构造函数)是忘记调用 InitializeComponent 方法。这个方法“告诉”视图创建和渲染它的内部组件。如果它没有被调用,你通常会发现你的视图看起来是空的,因为它的组件从未被创建。

【讨论】:

  • 必须等待一个小时才能获得赏金——很快就会这样做。再次感谢!
  • 不客气。我记得以前我自己也遇到过几次同样的问题,这非常令人沮丧。我很高兴能帮上忙。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多