3

好吧,我有一个继承用户控件(视图)的控件,并且我在使用用户控件(基本控件)时使用它,如果我这样做,这就是问题所在

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”的消息框。

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

4

4 回答 4

3

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

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

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

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

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

对 WPF 设计器加载失败进行故障排除

当 VS 2008 XAML 设计器视图尝试呈现 GUI 时会调用什么?

不要在 WPF 设计器(苹果酒)中这样做!

于 2010-09-02T21:51:04.213 回答
1

Petoj,我认为您应该问自己/描述为什么您想知道类型的名称以及为什么在设计时间不同时它会引起麻烦。除非您正在与风车作斗争并且在我看来不会得到合理的答案。

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

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

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

于 2010-09-03T18:23:13.047 回答
1

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

于 2010-09-03T05:21:38.580 回答
0

我还在学习 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 文件中分离出来的。我不认为这会是问题。

于 2010-09-02T21:31:11.093 回答