2015-01-06 49 views
2

我有一種情況,我需要爲Web用戶控件擁有兩種完全不同的佈局,但是對於控件的代碼隱藏保持相同非常重要。我可以讓兩個Web用戶控件(.ascx)共享相同的代碼隱藏類嗎?

有什麼辦法可以爲兩個不同的Web用戶控件使用相同的代碼隱藏?我試着改變Page指令來使用同一個類,但是偶爾當你編譯時,.designer.cs文件會被重複控件生成,所以你會得到一個編譯錯誤。

我也嘗試從一個普通的基類繼承,但是你不能看到這個類的任何控件,這使得很難採取這種方法。

或者有沒有辦法阻止爲「克隆」控件重新生成designer.cs類?

+0

你在代碼隱藏中有很多業務邏輯嗎?如果是這樣,可以將它放置在一個單獨的類中,並由代碼隱藏用於兩個用戶控件? –

+0

不是「業務邏輯」,而是驗證控件和處理輸入等。由於此代碼嚴重訪問控件,並且無法從基類中看到控件,所以我認爲這不會很好解決問題的方法:( – NickG

+0

)您可以創建一個包含您的驗證邏輯的靜態類,而不是基類,這些方法將作爲參數傳遞給您的控件。 –

回答

2

我剛纔在VS測試這個2012年

  1. 我加入2用戶控制
  2. 已刪除.ascx.cs.ascx.Designer.cs來自第二控件的文件
  3. 已修改Page第二控件的指令爲CodeBehindInherits屬性。不需要爲第二個控件生成Designer文件。

它的工作原理。我不知道這是否有效。 我已經通過在每個控件中添加一個Label並在代碼後面設置它的值來測試它。價值反映在兩個控件中。

如果在一個用戶控件中有一個asp.net控件,而在其他控件中不存在,則可能會遇到問題。

+0

.designer.cs文件有時會重新填充(我無法弄清楚何時!)當我這樣做時。 – NickG

+0

只有在嘗試將其轉換爲Web應用程序選項時,'.designer.cs'纔會重新生成。但是使用這種方法,您無法爲上述控件生成'.designer.cs',並在轉換時拋出錯誤。其他功能將按照應有的方式工作。嘗試一下。 – Bharadwaj

+0

謝謝你是對的。關鍵似乎是刪除文件而不是清空文件。這樣.designer.cs不會被重新創建。 – NickG

2

創建基類,並在那裏實現通用邏輯。然後從這個基類繼承控件。爲了從基類級別訪問控件,抽象獲取您需要的每個控件的基類級屬性。在子控件類中實現這些屬性。

public abstract class BaseControl : UserControl 
{ 
    public abstract TextBox FirstName { get; } 

    public void SomeLogicExample() 
    { 
    FirstName.Text = "Something"; 
    } 
} 

public class ControlA : BaseControl 
{ 
    public override TextBox FirstName 
    { 
    // txtFirstNameA is ID of TextBox, so it is defined in ControlA.designer.cs 
    get { return txtFirstNameA; } 
    } 
} 

public class ControlB : BaseControl 
{ 
    public override TextBox FirstName 
    { 
    // txtFirstNameB is ID of TextBox, so it is defined in ControlB.designer.cs 
    get { return txtFirstNameB; } 
    } 
} 

另一種方法是,在運行時定位控件;因爲你付出的搜索整個控件樹,你必須處理的控制沒有發現的情況:

public abstract class BaseControl : UserControl 
{ 
    public T GetControlByType<T>(Func<T, bool> predicate = null) where T : Control 
    { 
    var stack = new Stack<Control>(new Control[] { this }); 
    while (stack.Count > 0) 
    { 
     var control = stack.Pop(); 
     T match = control as T; 
     if (match != null) 
     { 
     if (predicate == null || predicate(match)) 
     { 
      return match; 
     } 
     } 

     foreach (Control childControl in control.Controls) 
     { 
     stack.Push(childControl); 
     } 
    } 

    return default(T); 
    }  

    public TextBox FirstName 
    { 
    get { return GetControlByType<TextBox>(t => t.ID == "txtFirstName"); } 
    } 

    public void SomeLogicExample() 
    { 
    FirstName.Text = "Something"; 
    } 
} 
+0

感謝您的回覆,但我選擇了我接受的答案,因爲它更簡單,只涉及按刪除鍵;) – NickG

+0

@NickG我強烈建議重新考慮您的決定,您正在搞亂並改變默認的asp.net/VS行爲可能會導致更長遠的麻煩。 –

1

除了@Ondrej Svejdar的正確答案之外,我建議你看看MVP design pattern,並可能將它用於Web窗體代碼。它的工作原理,我已經在一個大項目中嘗試過了,結果並不比在MVC項目中分離關注點差。有框架可以幫助你實現它,但由於某種原因,我更喜歡自己實現它(畢竟它是幾個基類和一個基本接口)

相關問題