【问题标题】:How to Correctly Reference Parent Form from UserControl如何从 UserControl 正确引用父窗体
【发布时间】:2013-07-23 22:57:46
【问题描述】:

所有,我有一个UserCostrol,我最近不得不更改它。这种改变要求我引用Parent 表单并使用该表单中的属性。这些引用似乎破坏了设计器 - 我遇到了一个错误

“无法将“System.Windows.Forms.Form”类型的对象转换为“Project.SettingsForm”类型”

Unable to cast object of type 'System.Windows.Forms.Form' to type 'Project.Form1' 中有描述。

我已经添加了一个属性来处理对Parent 表单的引用,如上面引用的答案中所述,但现在设计器错误说

“无法将‘System.Windows.Forms.Panel’类型的对象转换为‘Project.SettingsForm’类型”。

编译器抱怨的第一行在下面的代码中标有'<-- Here'

public partial class UiSettingFascia : UserControl, ISettingsControl
{
    public UiSettingFascia()
    {
        InitializeComponent();
    }

    private void UiSettingFascia_Load(object sender, EventArgs e)
    {
        LoadSettings();
        CheckBoxShowTabs.CheckedChanged += Workbook_StateChanged;
        CheckBoxShowVirticalScroll.CheckedChanged += Workbook_StateChanged;
        CheckBoxShowHorizontolScroll.CheckedChanged += Workbook_StateChanged;
    }

    public void LoadSettings()
    {
        UserSettings userSettings = UserSettings.Instance();
        ...
        MainRibbonForm mainRibbonForm = (ControlParent).MainRibbonForm; // <-- Here.
        ...
    }
}

为了尝试解决最初的问题 [“无法将 'System.Windows.Forms.Form' 类型的对象转换为 'Project.SettingsForm'”] 我创建了以下属性

public SettingsForm ControlParent
{
    get { return Parent as SettingsForm; }
}

我怎样才能解决这个问题 [“无法将类型为 'System.Windows.Forms.Panel' 的对象转换为类型 'Project.SettingsForm'”],同时保持 @ 的功能987654328@?

感谢您的宝贵时间。

【问题讨论】:

  • 使用事件与父表单对话。
  • 你为什么不直接使用:var settingsForm = (SettingsForm)this.ParentForm;
  • @AlexFilipovici 这就是重点,在 UserControl 初始化的设计时编译期间,控件不应该知道任何关于父表单类型的信息。我试图使用一个仍然不理想的属性来“抽象它”,显然......

标签: c# winforms user-controls designer


【解决方案1】:

看起来您需要编写一些设计时行为的代码。在设计时,UserControl 的父级实际上可能是 Visual Studio(或其某些组件)。这就是 Visual Studio 能够为您提供在设计时使用控件的 GUI 的方式——它实际上是控件的宿主;它实际上正在执行。

您可能需要在采用父表单的属性上设置一个属性,以便在设计时为其提供一些其他行为。另外,我认为 UserControls 上有一个名为 DesignMode 的属性,当控件处于设计模式时该属性是正确的——这样,您可以在设计时和运行时赋予控件不同的行为。 MSDN 上有很多关于创建控件和配置其设计时与运行时行为的文章。

【讨论】:

    【解决方案2】:

    添加this extension method:

    public static class DesignTimeHelper
    {
        public static bool IsInDesignMode
        {
            get
            {
                bool isInDesignMode = (
                    LicenseManager.UsageMode == LicenseUsageMode.Designtime || 
                    Debugger.IsAttached == true);
                if (!isInDesignMode)
                {
                    using (var process = Process.GetCurrentProcess())
                    {
                        return process
                            .ProcessName.ToLowerInvariant()
                            .Contains("devenv");
                    }
                }
                return isInDesignMode;
            }
        }
    }
    

    然后,在您的 LoadSettings 方法中:

    public void LoadSettings()
    {
        if (!DesignTimeHelper.IsInDesignMode)
        {
            var settingsForm = (SettingsForm)this.ParentForm;
        }
    }
    

    【讨论】:

    • +1。谢谢你的帮助。这看起来很有希望,但是在尝试将UserControl 添加到我的表单时,我仍然收到“无法投射...”。有关更多信息,请参阅我的编辑...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多