【问题标题】:WPF Getting a RegionName from a View ClassWPF 从视图类中获取 RegionName
【发布时间】:2018-10-16 12:53:26
【问题描述】:

WPF 应用程序,使用 Prism。

我正在使用多阶段模块初始化程序,并且在模块的初始化过程中,我希望模块能够自我检查视图并注册其中定义的任何区域。

我正在使用类似于以下代码的代码来自我检查视图模型类并注册其他内容,但我不知道如何反映到视图中。

protected void SelfInspectRegions()
{
    var assm = Assembly.GetAssembly(this.GetType()).GetTypes();
    foreach (var type in assm)
    {
        if(type.IsSubclassOf(typeof(UserControl)))
        {
            var a = type;
        }
    }
}

下面是我想自行注册的基于选项卡的区域(在视图/用户控件上定义)的示例;

                <controls:ChTabControlModelAware x:Name="OrderProcessingDocumentDetailRegion"  
                                                           cal:RegionManager.RegionManager="{Binding RegionManager, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type shells:FormShell}}}"
                                                           cal:RegionManager.RegionName="Order Processing:DocumentDetailRegion"
                                                           cal:RegionManager.RegionContext="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
                                                           Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="1" VerticalAlignment="Stretch"
                                                           HorizontalAlignment="Stretch">

                    <bindings:EventToCommandBehavior.EventBindings>
                        <bindings:EventBinding Command="{Binding SelectedDetailTabChangedCommand}"
                                  CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=controls:TabControl}, Path= SelectedItem.DataContext.HeaderInfo}"
                                  EventName="SelectionChanged" RaiseOnHandledEvents="True"
                                  PassEventArgsToCommand="True" />
                    </bindings:EventToCommandBehavior.EventBindings>
                </controls:ChTabControlModelAware>

主要我想提取该行中定义的 RegionName;

cal:RegionManager.RegionName="Order Processing:DocumentDetailRegion"

我不知道该怎么做,如果有任何帮助,我们将不胜感激

非常感谢

兰斯

2018 年 17 月 10 日更新:我想要实现的目标。

我正在编写一个 WPF 应用程序框架,其中包含大约 30 个模块(并且正在扩展),它们都订阅和注入服务。

我的所有区域都在视图中声明,并且有很多。由于我的框架中的开发要求,现在模块需要在模块初始化阶段预先注册它们的区域。原因之一是某些服务以特定区域为目标,并且每个主机都具有独特的操作设置。目前主机模块负责设置,这意味着如果对服务的操作设置进行更改,则需要在模块和项目之间进行大量剪切和粘贴。通过主机预注册,在模块初始化中,服务模块知道哪些模块使用它的服务,并且可以将设置类注入到主机模块设置视图模型中以供用户交互。操作设置的更改只需要在服务模块中修改,而不是在使用它的所有各种主机模块中。

我一直在寻找一种简单的方法来从众多模块程序集中提取名称,而无需显式声明它们或使用声明性属性装饰视图模型。

【问题讨论】:

  • RegionName 是在 DependencyObject 上设置的附加属性,例如一个 ChTabControlModelAware 实例。你不能从课堂上得到它。
  • 我会建议你一个更好的方法:不要将区域名称定义为 XAML 中的字符串常量。相反,创建一个包含public const strings 和区域名称的static class RegionNames。然后,您可以在 XAML 中使用 x:Static 设置区域名称,并在初始化时使用反射从 RegionNames 类中获取所有名称。
  • 你想达到什么目的? RegionManager.RegionName="SomeRegionName" 通常会将控件注册为区域管理器。

标签: c# wpf reflection prism region-management


【解决方案1】:

我想获取实际区域名称的最简单方法是在区域管理器注册完成时拦截它们。

您应该注册自己的 IRegionManager 实现,它将所有内容转发到真实事物,但将在注册期间通过它的所有区域名称传递到您的区域名称注册表。

【讨论】:

  • 这样的缺点是注册只发生在视图被使用时,在需要操作配置的复杂服务的情况下这为时已晚。该服务可以测试设置是否已初始化并提示用户进行配置,但会强制用户访问视图以进行初始化,然后访问设置屏幕。我认为我无法避免它,尤其是在需要设置或选择加入/退出的情况下。 View/ViewModel 必须通过属性声明区域,以便服务可以在初始化时完成它的工作。
  • 所以你的意思是用属性替换附加属性?这样服务解析属性来知道区域,视图解析它来注册区域。听起来可行。但如果我必须实现这一点,我实际上更喜欢每个模块的静态类,其中包含其所有区域名称并反映到其中。但是你需要一些东西来强制执行,也许就像在预构建步骤中解析 xaml 并在找到 RegionName="literal" 时抛出错误一样简单......
  • 我不确定如何用属性替换附加属性。我想我要做的是将区域保留在视图上,并将 RegionDeclarationAttribute 放在 ViewModel 上。这样我就可以在模块初始化时注册该区域,如果 ViewModel 以非可视方式加载,则服务可以使用正确的服务 ViewModel 装饰主机 ViewModel,这些服务 ViewModel 无论如何都会通过服务 Views 加载。
  • 您打算如何强制属性与 xaml 匹配?如果不强制执行,不匹配(从而导致错误)出现只是时间问题。
  • 这通常不是 WPF 的问题吗?几乎我所有的视图都有“当 DataContext 未知时未解析的绑定路径”警告..​​....这些年来我一直在这样做,但我错过了一些东西,不是吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 1970-01-01
  • 2020-11-08
  • 2021-12-04
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
相关资源
最近更新 更多