2016-04-13 7 views
2

Я добавил несколько скриншотов и шагов для воспроизведения ниже.Как создать UserControl с WinForms на основе другого UserControl?

Моя модель данных имеет базовый класс, назовем его CommonThing который имеет много свойств. Тогда есть несколько специализированных версий этого класса с дополнительными свойствами. Теперь я хочу создать пользовательский интерфейс для ввода данных в эту модель.

Я создал UserControl, который содержит элементы управления для всех общих свойств, как это:

internal partial class CommonThingControl : UserControl { 

    public CommonThingControl() { 
     InitializeComponent(); 
    } 

    // Controller code 
} 

Это также добавляет CommonThingControl.Designer.cs, который заполняется дизайнером GUI.

теперь я создал SpecialFooThingControl как UserControl и изменил заголовок класса следующим образом:

internal partial class SpecialFooThingControl : CommonThingControl { 

    // implementation 
} 

Когда я теперь открыть SpecialFooThingControl в конструкторе GUI, я вижу штурвал CommonThingControl, но все они заблокированы , У меня, однако, есть TableLayoutPanel в CommonThingControl. Я хочу добавить материал, но ничего не могу изменить, и когда я пытаюсь перетащить элемент управления в TableLayoutPanel, курсор мыши становится значком «Нет парковки», и VS не позволяет мне. Это даже происходит, когда я устанавливаю аксессуар TableLayoutPanel в public.

I может переместить элемент управления в TableLayoutPanel через схему документа, но когда я затем восстановить проект, он исчезает из пользовательского интерфейса.

Это то, чего я пытаюсь достичь с дизайнером пользовательского интерфейса, и мне нужно установить его вручную или есть какой-то дополнительный шаг, который я забыл?

Вот что я сделал:

Во-первых, создал пользовательский элемент управления, это просто. Я создал панель макета таблицы, которую я установил в Protected, потому что я хочу добавить к ней. Common Control

Это код FooControl.cs:

namespace GuiTest { 
    public partial class FooControl : UserControl { 
     public FooControl() { 
      InitializeComponent(); 
     } 
    } 
} 

И FooControl.Designer.cs:

namespace GuiTest { 
    partial class FooControl { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) { 
      if (disposing && (components != null)) { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Component Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() { 
      this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 
      this.label1 = new System.Windows.Forms.Label(); 
      this.textBox1 = new System.Windows.Forms.TextBox(); 
      this.tableLayoutPanel1.SuspendLayout(); 
      this.SuspendLayout(); 
      // 
      // tableLayoutPanel1 
      // 
      this.tableLayoutPanel1.ColumnCount = 2; 
      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 
      this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 
      this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); 
      this.tableLayoutPanel1.Controls.Add(this.textBox1, 1, 0); 
      this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; 
      this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); 
      this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 
      this.tableLayoutPanel1.RowCount = 1; 
      this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); 
      this.tableLayoutPanel1.Size = new System.Drawing.Size(360, 28); 
      this.tableLayoutPanel1.TabIndex = 0; 
      // 
      // label1 
      // 
      this.label1.AutoSize = true; 
      this.label1.Location = new System.Drawing.Point(3, 7); 
      this.label1.Margin = new System.Windows.Forms.Padding(3, 7, 3, 0); 
      this.label1.Name = "label1"; 
      this.label1.Size = new System.Drawing.Size(25, 13); 
      this.label1.TabIndex = 0; 
      this.label1.Text = "Foo"; 
      // 
      // textBox1 
      // 
      this.textBox1.Dock = System.Windows.Forms.DockStyle.Top; 
      this.textBox1.Location = new System.Drawing.Point(34, 3); 
      this.textBox1.Name = "textBox1"; 
      this.textBox1.Size = new System.Drawing.Size(323, 20); 
      this.textBox1.TabIndex = 1; 
      // 
      // FooControl 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.Controls.Add(this.tableLayoutPanel1); 
      this.Name = "FooControl"; 
      this.Size = new System.Drawing.Size(360, 28); 
      this.tableLayoutPanel1.ResumeLayout(false); 
      this.tableLayoutPanel1.PerformLayout(); 
      this.ResumeLayout(false); 

     } 

     #endregion 

     protected System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 
     private System.Windows.Forms.Label label1; 
     private System.Windows.Forms.TextBox textBox1; 
    } 
} 

Теперь я добавил BarControl: Adding UserControl

Теперь я изменил простираться от UserControl до FooControl в BarControl.cs:

namespace GuiTest { 
    public partial class BarControl : FooControl { 
     public BarControl() { 
      InitializeComponent(); 
     } 
    } 
} 

BarControl.Designer.cs:

namespace GuiTest { 
    partial class BarControl { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) { 
      if (disposing && (components != null)) { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Component Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() { 
      components = new System.ComponentModel.Container(); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     } 

     #endregion 
    } 
} 

И вот как это получается: Locked Layout Panel

ответ

1

Причина, по которой элементы управления в CommonThingControl заблокированные происходит потому, что суб-класс SpecialFooThingControl не имеет доступа к ним (они в частном порядке).

Что вы можете сделать, однако, в дизайнере для CommonThingControl - это изменение свойства модификаторов на них, что позволит вам потреблять/изменять их в вашем подклассе. Вы должны сделать это на каждом отдельном элементе управления и можете просто изменить раскрывающийся список в окне «Свойства». Вероятно, вы можете изменить их в файле commonthingcontrol.designer.cs, но я также опасаюсь, что этот файл будет автоматически сгенерирован, и изменения могут быть легко переписаны, если вы не будете осторожны.

enter image description here

Я рекомендую использовать что-то вроде Protected, чтобы убедиться, что они видны под-контроля, но предотвратить их злоупотребления за пределами цепи наследования.

EDIT

Так дальше, глядя на это показывает, что это ограничение TableLayoutPanel. Взятые из https://msdn.microsoft.com/en-us/library/ms171689.aspx:

избежать визуального наследования Контроль TableLayoutPanel не поддерживает визуальное наследование в конструкторе Windows Forms. Элемент управления TableLayoutPanel в производном классе отображается как «заблокированный» во время разработки.

+0

Это именно то, что я сделал, но он по-прежнему отображается как заблокированный. Но я также застрял на VS2010, потому что мне приходится взаимодействовать с некоторыми сторонними библиотеками, которые не работают с новыми версиями VS. Возможно, это ошибка в VS 2010. – rabejens

+0

@rabejens Вы пробовали пересоздать/перезапустить Visual Studio? Иногда это помогает верить или нет. Если вы их настроили на любое другое, чем 'Private', а ваш подконтроль находится в одном проекте, то это действительно должно работать. – Ian

+0

@rabejens вы могли бы добавить скриншот для дальнейшей разработки, если это не поможет? – Ian

0

Благодаря контроля доступности, вы не можете обновить их. Для этого перейдите в ваш CommonThingControl.Designer.cs, изменится Exemple private Button MyButton1 к protected Button MyButton1

+0

Я уже сделал это, но он все еще заблокирован. – rabejens

+0

И если вы перестраиваете, удалите свой контроль 'SpecialFooThingControl' и снова добавьте его? – Panda

Смежные вопросы