2015-03-19 62 views
2

我正在嘗試創建基類以更改現有表單的用戶界面。 我剛開始開發類,並有下面的代碼:如何使用基類設置Control和WinForm樣式?

public class UI_1:Form 
{   
    public UI_1() 
    { 
     FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 
     Font = new System.Drawing.Font("Segoe UI", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 
     BackColor = System.Drawing.SystemColors.HotTrack;   

    } 
} 

public partial class Form_LoginNew : UI_1 
{  
    public Form_LoginNew() 
    { 
    } 
} 

我將這個基類繼承來我現有的形式(Form_LoginNew)如上圖所示。在測試時,「FormBorderStyle」被設置/更新...但「BackColor」&「字體」不會改變。爲什麼它不工作?

此外,請讓我知道如何使用此基類來更改(button,labels ..等)的控件樣式。請記住,表單和控件已經存在。另外,我不能和WPF一起去。

+1

屬性在InitializeComponent中被初始化爲它們的值,大多數情況下,如果它們被設計者觸動了。它們位於表單的.designer.cs文件中。所以你在這裏做的是設置默認值,在InitializeComponent中被覆蓋,因爲這是在構造函數之後調用的。 – Robinson 2015-03-19 12:13:06

+0

當我嘗試時工作得很好。無論你做錯什麼,都不能從代碼片段中看到。我的水晶球竊聽了關於缺少的InitializeComponent()調用的一些信息,但那不可能。 – 2015-03-19 12:54:12

+0

@Robinson:你是對的。如果我設置/替換.designer.cs文件中的'BackColor'屬性....它工作。但是,如何使用上面的基類實現這一點?這個項目有很多種形式,我想用我將以現有形式繼承的基類來實現。謝謝:) – 911Rapid 2015-03-19 13:49:44

回答

2

創建原始表單時,它們很可能是使用設計器構建的。

使用BackColor爲例,如果已經在設計被改變,這將在派生類中的InitializeComponent發生(基類的構造函數後調用),因此不管你設置有有效地忽略。

你可以做這樣的事情在你的基類

public override System.Drawing.Color BackColor 
{ 
    get 
    { 
     return System.Drawing.SystemColors.HotTrack; 
    } 
    set 
    { 
     // Don't do anything here 
    } 
} 

如果你試試這個,你會發現你不能在設計改變BackColor派生形式,因爲二傳手沒有做任何東西。

關於你的問題

另外,請讓我知道如何使用這個基類的改變(按鈕,labels..etc)控件樣式。請記住,表單和控件已經存在。另外,我不能和WPF一起去。

你可以創建自己的ControlsCollection,這樣的事情:

public class MyControlCollection : Control.ControlCollection 
{ 
    public MyControlCollection(Control owner) : base(owner) 
    { 
    } 

    public override void Add(Control value) 
    { 
     // Modify whatever type of control you want to here 
     if (value is Button) 
     { 
      // As an example, I will set the BackColor of all buttons added to the form to red 
      Button b = (Button)value; 
      b.BackColor = Color.Red; 
     } 
     base.Add(value); 
    } 
} 

要在基類中使用,所有你需要做的就是重寫CreateControlsInstance方法:

protected override Control.ControlCollection CreateControlsInstance() 
{ 
    return new MyControlCollection(this); 
} 
+0

謝謝加里爲完整的解決方案:) – 911Rapid 2015-03-19 15:34:25

2

我建議不要嘗試使用繼承來設置樣式,而是會推薦一組可以爲您應用樣式的擴展方法。

當我試着做了一個繼承FormThatNeedsStyle的表單時,我在構造函數中爲FormThatNeedsStyle設置的樣式正在工作(甚至在設計器中)。

public partial class FormThatNeedsStyle : Form 
{ 
    public FormThatNeedsStyle() 
    { 
    InitializeComponent(); 
    this.Style(); 
    } 
} 

// Extension method class to apply styles 
public static class Styles 
{ 
    public static void Style(this Form form) 
    { 
    form.BackColor = Color.HotPink; 

    foreach (var control in form.Controls) 
    { 
     // Apply desired styles to controls within the form 
     if (control is Button) 
     (control as Button).Style(); 
    } 
    } 

    public static void Style(this Button button) 
    { 
    button.FlatStyle = FlatStyle.Flat; 
    } 
} 
+0

爲什麼反對繼承?我測試了上面給出的擴展方法。有用 。但是,我想知道爲什麼你更喜歡擴展方法。謝謝你:) – 911Rapid 2015-03-19 15:33:31

+0

我不一定反對繼承。這聽起來像是有問題,而不是試圖使它繼承工作,我認爲使用不同的方法可能會更容易。我也想不到通過繼承來處理樣式按鈕和其他控件的好方法。 – 2015-03-19 15:44:33

+2

我喜歡這種方法。注意行爲的一個關鍵差異是Jeff的答案中的樣式不適用於在運行時添加的控件。你是否想要這將取決於你正在使用的形式是如何設計的 – 2015-03-19 16:22:58