【问题标题】:WPF get Type in Design time?WPF 在设计时获取类型?
【发布时间】:2010-09-07 06:27:01
【问题描述】:

好吧,我有一个继承 usercontrol(view) 的控件,并且我在使用它时使用它,因为您使用的是 usercontrol(基本控件),如果我这样做了,这就是问题

MessageBox.Show(this.GetType().ToString());

我在运行时和设计时得到不同的消息,在设计时我得到视图,我在运行时得到继承视图的 xaml 文件的类名...

如何在设计时获取继承类类型而不是基类?

这里有一些代码:

首先我们有视图类

public class View : UserControl
{
    public override void OnApplyTemplate()
    {
        MessageBox.Show(this.GetType().ToString());
        base.OnApplyTemplate();
    }
}

然后我们有一个 XAML 文件:

<local:View x:Class="WpfApplication2.Test"
             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" 
             xmlns:local="clr-namespace:WpfApplication2"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

    </Grid>
</local:View>

现在,如果您在 VisualStudio 2010 中编译并打开“WpfApplication2.Test”,您将看到一个显示“WpfApplication2.View”的消息框..

但是,如果您将 Test 控件放在 MainWindow 中并按 Run(F5),您会得到 WpfApplication2.Test.. 我想要的是在设计时具有与运行时相同的响应...

【问题讨论】:

  • 我不完全了解您的情况。您可以发布您的控件的 XAML sn-p 以及您正在执行此消息框调用的一些上下文吗?另外,对您最终要完成的工作的进一步解释可能会有所帮助?可能有更有效的方法来做你最终想要的。
  • 什么是“设计时间”?您的意思是当您在 IDE 中将鼠标悬停时,它会显示“查看”?
  • 对其进行了编辑以进一步解释并添加了一些代码..
  • 我复制了你的项目,但你有没有注意到,如果你进入显示测试控件的窗口,已经在设计时,窗口会提示“测试”?
  • 是的,但如果您在设计模式下打开测试控件,它会显示视图

标签: c# xaml design-time


【解决方案1】:

嗯,问题在于 Visual Studio 2010 中的 XAML 设计器没有实例化在代码隐藏中声明的实际类。相反,它只实例化它的基类。

如果您考虑一下,当您修改 XAML 时,实际上是在修改代码隐藏中声明的类,因为它是与从 XAML 创建的另一部分相结合的部分类。因此设计器无法创建您的类的实例:它仍在创建中。

如果不编写以某种方式与 Visual Studio 本身交互以询问实际正在设计什么文件的代码,我认为您将无法完成您所追求的目标。

您至少可以通过检查 DesignerProperties.GetIsInDesignMode() 来保护您的代码。

有关一些相关信息,请参阅这些链接:

Troubleshooting WPF Designer load failures

What gets called when the VS 2008 XAML Designer view tries to render the GUI?

Don't do that in the WPF Designer (Cider)!

【讨论】:

    【解决方案2】:

    当您设计派生控件时,VS2010 Designer (Cider) 正在实例化基类的实例。你对此无能为力。

    【讨论】:

    • 好吧,我不想改变苹果酒我只是想知道类型或类型的名称,这不必由 GetType 完成,它可以是任何其他方法或属性..
    【解决方案3】:

    Petoj,我认为你应该问自己/描述为什么你想知道类型的名称,以及为什么它在设计时间不同时会造成麻烦。除非你在和风车搏斗,而且在我看来不会得到合理的答案。

    更新——简单解决方法的伪代码:

    if (IsDesignTime)
       use this.GetType()
    else
       use this.GetType().BaseType
    

    更新 2: 在设计时,无法获取正在设计的 descendant 类的名称。问题可能应该以不同的方式解决,而不是取决于实际类的名称。

    【讨论】:

    • 好吧,我现在有一个视图和视图模型(或它们的类型)的列表,当我在设计时我想将 DataContext 设置为正确的视图模型类型但能够做到这一点,我需要输入,以便我可以比较类型。
    • @Petoj 用合理的(恕我直言)解决方法更新了我的答案。
    • @Petoj 再次阅读您的问题。现在我明白了:你想要 descendant 类的名称。正如 Omer Mor 在他的回答中指出的那样,可能没有办法得到它——事实上,微软技术中的视觉设计师确实实例化了 base 类,而不是后代类正在实际设计中。因此,在您的情况下,通过以完全不同的方式了解类型名称来解决您尝试解决的问题可能会更快。
    【解决方案4】:

    我还在学习 WPF,所以这可能不是您想要的。

    在设计时和运行时,this.GetType().ToString();在消息框中返回给我“WpfApplication2.View”。

    所以视图在两种模式下都返回。我会声明我对你的代码做了一点改动。

    namespace WpfApplication2
    {
        /// <summary>
        /// Interaction logic for View.xaml
        /// </summary>
        public partial class View : UserControl
        {
            public override void OnApplyTemplate()
            {
                MessageBox.Show(this.GetType().ToString());
                base.OnApplyTemplate();
            }
        }
    }
    

    我将它标记为部分类,而不仅仅是类,因为 XAML 显然是从 .cs 文件中分离出来的。不过我认为这不是问题。

    【讨论】:

    • 在他的问题中,“View”类是“Test”类的基类。 “Test”类是在 Test.xaml 的代码隐藏中定义的部分类。
    • 没问题,不过值得一试。我记得在嵌套视图时,VisualStudio 的 DesignMode 属性的问题有些无用。 @Mike Schenk,感谢您澄清这一点。在重新阅读确实让我感到困惑的代码时,没有看到测试继承自视图。
    • 编辑:Partial 只适用于一个类(你不能让一个类偏于多个类),并且 partial 只在同一个程序集中......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    相关资源
    最近更新 更多