【问题标题】:C# WinForms Base UserControlC# WinForms 基础用户控件
【发布时间】:2019-10-28 15:15:26
【问题描述】:

我在使用 UserControls 的 VS2019 中遇到了一些问题。

我有一个基本用户控件 (WinForms),我希望从中继承所有其他用户控件。基本控件提供了许多我需要的常用属性。

public partial class MyBaseControl : System.Windows.Forms.UserControl
{

    internal Int32 _caseID;
    internal object _objectID;

    public int CaseID { get => _caseID; set => _caseID = value; }
    public object ObjectID { get => _objectID; set => _objectID = value; }

    internal virtual void MakeScreenReadOnly()
    {
    }
    public MyBaseControl()
    {
        Type systemType = this.GetType();
        PropertyInfo propertyInfo = systemType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        this.AutoScroll = true;

    }

}

当应用程序运行时,继承此基本控件的控件都可以正常工作,但我无法在设计器中查看该控件。用户控件是

public partial class AddressControl : MyBaseControl
    {
....
}

我得到了错误

The service System.Windows.Forms.Design.IEventHandlerService already exists in the service container. Parameter name: serviceType

尝试在设计器中查看 AddressControl 时。

这曾经在早期版本的 Visual Studio 中有效。有没有人有任何想法?

【问题讨论】:

  • 我发现了一些有趣的东西。该解决方案由 3 个项目组成,一个数据访问库 (.Net Framework)、UI(包含详细控件的 WinForms 项目)和一个支持库 (.NET Core)。如果我删除支持库并引用已编译的 DLL,它似乎一切都很好。如果我引用该项目,那就是我获得项目的时候。 UI 项目同时引用数据访问和支持库,支持库引用数据访问库
  • 用户控件构造函数是否应该包含 InitializeComponent();?
  • 我已经添加了,但没有解决问题
  • 之后您是否进行了干净的重建?
  • 移除那个反射的东西。在 UserControl 中,您可以在其构造函数中设置 this.DoubleBuffered = true;this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);。 -- 确保在基类和派生类中没有重复的属性,例如 [Designer(GetType(...)]。在这种情况下,从派生类中删除属性。 -- 不要在基类中做任何与设计时间/设计模式相关的事情(检查if (DesignMode) (...)),尤其是在Load 事件中。如果需要设置某些内容,请覆盖 OnHandleCreated()OnLayout() 或两者。

标签: c# winforms inheritance user-controls


【解决方案1】:
  • 退出 Visual Studio。
  • 打开文件资源管理器:导航到包含您的项目的文件夹。
  • 删除“bin”和“obj”文件夹。
  • 再次打开 Visual Studio 并打开并重新编译项目。

【讨论】:

    【解决方案2】:

    您可以尝试重新创建用户控件。

    从项目中排除旧控件以将其保留在磁盘上。

    将旧文件移出项目文件夹(MyBaseControl.cs & MyBaseControl.Designer.cs)。

    使用Project > Add > User control 向导。

    把你的旧代码复制进去。

    并且不要从构造函数中删除InitializeComponent();:在之后添加您的代码。

    如果 Visual Studio 没有损坏,它可能会工作并解决您的问题,否则您可以尝试修复或卸载并重新安装它。

    这是我尝试过的:

    • 我添加了这个用户控件:

      public partial class UserControl1 : UserControl
      {
        public UserControl1()
        {
          InitializeComponent();
        }
      }
      
    • 我编译。

    • 我添加了另一个用户控件并更改了父控件:

      public partial class UserControl2 : UserControl1
      {
        public UserControl2()
        {
          InitializeComponent();
        }
      }
      

    它工作正常,并且设计器都正确显示。

    接下来我添加了您的代码同时保持InitializeComponent() 调用

    public partial class UserControl1 : UserControl
    {
      internal Int32 _caseID;
      internal object _objectID;
    
      public int CaseID { get => _caseID; set => _caseID = value; }
      public object ObjectID { get => _objectID; set => _objectID = value; }
    
      internal virtual void MakeScreenReadOnly()
      {
      }
      public UserControl1()
      {
        InitializeComponent();
        Type systemType = this.GetType();
        PropertyInfo propertyInfo = systemType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        this.AutoScroll = true;
      }
    }
    

    我编译。

    一切正常。

    【讨论】:

    • 很遗憾,这也没有用。今晚我将在我的家用电脑上尝试,看看我是否在那里得到相同的行为,但我尝试卸载/安装
    • 如果您在不更改任何内容的情况下创建新的用户控件会发生什么:您是否能够打开设计器并看到空的控制界面?
    • 是的,如果我将 AddressControl 更改为从 UserControl 继承,它也会正确显示。
    • 它对我不起作用。在这种情况下,我看不到 UserControl2。我收到与我的支持 DLL 相关的不同错误(请参阅我对原始帖子的评论)。我开始认为 Support DLL 由于某种原因引起了问题。不知道为什么是唯一的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多