2010-09-04 3 views
0

У меня есть функция, которая устанавливает мою ссылку в качестве кнопки по умолчанию для панели.Функция многократного использования__Передателя в asp.net

protected void Page_PreRender(object sender, EventArgs e) 
    { 
     string addClickFunctionScript = @"function addClickFunction(id) { 
       var b = document.getElementById(id); 
       if (b && typeof(b.click) == 'undefined') 
       b.click = function() { 
        var result = true; 
        if (b.onclick) result = b.onclick(); 
        if (typeof(result) == 'undefined' || result) 
        eval(b.getAttribute('href')); 
       } 
      };"; 

     string clickScript = String.Format("addClickFunction('{0}');", lbHello.ClientID); 

     Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true); 
     Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + lbHello.ClientID, clickScript, true); 
    } 

Это прекрасно работает. Как сделать это повторно используемым для всех моих страниц моего приложения. На одной странице могут быть несколько кнопок ссылок и несколько панелей .... Любое предложение ...

ответ

3

Самый чистый способ - использовать настраиваемый серверный элемент управления, который наследует от LinkButton. На самом деле это похоже на the blog post от вашего earlier question. Все, что вам нужно сделать, это переопределить событие OnPreRender и вставить код, который у вас есть, при изменении lbHello.ClientID до this.ClientID, чтобы обратиться к конкретному экземпляру этого элемента управления. Это не должно занимать более 10 минут. Как только это будет сделано, вы можете использовать столько элементов управления, сколько хотите на одной странице, и легко поддерживать их на разных страницах вашего приложения.

Возможно, эта статья MSDN может быть полезной, если следовать моим инструкциям ниже, в частности разделу «Создание сервера»: Walkthrough: Developing and Using a Custom Web Server Control. Вот шаг за шагом руководство для достижения этого:

  1. В существующем решении добавить новый проект ASP.NET управления сервера (щелкните правой кнопкой мыши на ваше решение от Обозревателе решений -> Add New Project -> ASP.NET сервера Control). Назовите его LinkButtonDefault (вы можете, конечно, изменить название).
  2. Переименовать ServerControl1.cs в LinkButtonDefault.cs
  3. Переименовать пространство имен в файле для CustomControls
  4. Выполните шаги 12-14 в статье MSDN, открыв AssemblyInfo.cs файл (содержащийся в Properties папке проекта). Добавьте эту строку в конец файла: [assembly: TagPrefix("CustomControls", "CC")]
  5. В LinkButtonDefault.cs добавить этот код, чтобы переопределить OnPreRender событие:

кода (обратите внимание на использование this.ClientID):

protected override void OnPreRender(EventArgs e) 
    { 
     string addClickFunctionScript = @"function addClickFunction(id) { 
      var b = document.getElementById(id); 
      if (b && typeof(b.click) == 'undefined') 
      b.click = function() { 
       var result = true; 
       if (b.onclick) result = b.onclick(); 
       if (typeof(result) == 'undefined' || result) 
       eval(b.getAttribute('href')); 
      } 
     };"; 

     string clickScript = String.Format("addClickFunction('{0}');", this.ClientID); 

     Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true); 
     Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + this.ClientID, clickScript, true); 

     base.OnPreRender(e); 
    } 

Вы также можете хотите обновить сгенерированный код атрибута над объявлением класса, который начинается с [ToolboxData("<{0}:, чтобы использовать LinkButtonDefault вместо ServerControl1. Именно для нового проекта Server Control. Я настоятельно рекомендую прочитать вышеупомянутую статью MSDN, чтобы воспользоваться другими возможностями, такими как добавление элементов управления в панель инструментов, если вам нужно это сделать.

После выполнения этих шагов вы должны иметь LinkButtonDefault.cs файл, который напоминает это:

using System; 
using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace CustomControls 
{ 
    [DefaultProperty("Text")] 
    [ToolboxData("<{0}:LinkButtonDefault runat=server></{0}:LinkButtonDefault>")] 
    public class LinkButtonDefault : LinkButton 
    { 
     [Bindable(true)] 
     [Category("Appearance")] 
     [DefaultValue("")] 
     [Localizable(true)] 
     public string Text 
     { 
      get 
      { 
       String s = (String)ViewState["Text"]; 
       return ((s == null) ? "[" + this.ID + "]" : s); 
      } 

      set 
      { 
       ViewState["Text"] = value; 
      } 
     } 

     protected override void RenderContents(HtmlTextWriter output) 
     { 
      output.Write(Text); 
     } 

     protected override void OnPreRender(EventArgs e) 
     { 
      string addClickFunctionScript = @"function addClickFunction(id) { 
       var b = document.getElementById(id); 
       if (b && typeof(b.click) == 'undefined') 
       b.click = function() { 
        var result = true; 
        if (b.onclick) result = b.onclick(); 
        if (typeof(result) == 'undefined' || result) 
        eval(b.getAttribute('href')); 
       } 
      };"; 

      string clickScript = String.Format("addClickFunction('{0}');", this.ClientID); 

      Page.ClientScript.RegisterStartupScript(this.GetType(), "addClickFunctionScript", addClickFunctionScript, true); 
      Page.ClientScript.RegisterStartupScript(this.GetType(), "click_" + this.ClientID, clickScript, true); 

      base.OnPreRender(e); 
     } 
    } 
} 

Теперь вернуться к вашей веб-приложения и добавить ссылку на проект CustomControls. Вы должны сделать это на вкладке «Добавить ссылку» Project, так как я предложил добавить этот проект в существующее решение. Если вы хотите, чтобы вы могли создать вышеупомянутый проект в своем собственном решении, вы добавили бы ссылку на его файл .dll, используя вкладку Browse. После того, как ссылка была добавлена, вы готовы использовать новый элемент управления LinkButtonDefault.

Для использования элементов управления вы можете использовать директиву @ Register на каждой странице элемент управления, или вы можете добавить его в Web.config и получить легкую ссылку на него во всем приложении. Я покажу вам оба метода ниже. Исходя из вашего вопроса, я думаю, вы захотите добавить его в Web.config. См. Статью MSDN, и вы найдете эту информацию на полпути вниз по странице в разделе «Префикс тега».

Использование @ Register директивы:

Перейти к нужной .aspx страницы и добавить Register директиву в верхней части каждой страницы вы хотите использовать элемент управления в:

<%@ Register Assembly="CustomControls" Namespace="CustomControls" TagPrefix="CC" %> 

В то же страницы, теперь вы можете использовать несколько экземпляров элемента управления. Вот пример:

<p><strong>1st Panel:</strong></p> 
<asp:Label runat="server" ID="helloLabel" /> 
<asp:Panel ID="Panel1" runat="server" DefaultButton="lbHello"> 
    First name: 
    <asp:TextBox runat="server" ID="txtFirstName" /> 
    <CC:LinkButtonDefault ID="lbHello" runat="server" Text="Click me" OnClick="lbHello_Click" 
     OnClientClick="alert('Hello, World!');" /> 
</asp:Panel> 

<p><strong>2nd Panel:</strong></p> 
<asp:Label runat="server" ID="fooBarLabel" /> 
<asp:Panel ID="Panel2" runat="server" DefaultButton="lbFooBar"> 
    Other: 
    <asp:TextBox runat="server" ID="TextBox1" /> 
    <CC:LinkButtonDefault ID="lbFooBar" runat="server" Text="Click me" OnClick="lbFooBar_Click" /> 
</asp:Panel> 

В коде позади (.aspx.cs) вам нужно будет добавить:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // example of adding onClick programmatically 
    lbFooBar.Attributes.Add("onClick", "alert('Foo Bar!');"); 
} 

protected void lbHello_Click(object sender, EventArgs e) 
{ 
    helloLabel.Text = String.Format("Hello, {0}", txtFirstName.Text); 
} 

protected void lbFooBar_Click(object sender, EventArgs e) 
{ 
    fooBarLabel.Text = String.Format("FooBar: {0}", TextBox1.Text); 
} 

Использование Web.config:

Чтобы использовать Web.config держать точно такую ​​же разметку и код, используемые в приведенном выше примере. Выполните следующие шаги:

  1. Удалить директиву @ Register, используемую для разметки .aspx.
  2. Открыть файл Web.config для вашего веб-приложения.
  3. Найдите раздел <system.web>...</system.web>.
  4. Добавьте следующее отображение в этом разделе:

Mapping:

<pages> 
    <controls> 
    <add assembly="CustomControls" namespace="CustomControls" tagPrefix="CC" /> 
    </controls> 
</pages> 

Recompile и все должно строить успешно. При этом вам больше не нужно указывать директиву @ Register на каждой отдельной странице.

Если вы застряли и у вас есть какие-либо вопросы, дайте мне знать. Просто внимательно прочитайте все выше, потому что это длинный пост с большим количеством кода.

+0

для этого замечательного решения ... –

0

Вы можете создать класс (назовем его Foo), который происходит из System.Web.UI.Page и абстрагирует ваш метод до точки где он многоразовый. Все ваши ContentPages должны быть получены из Foo вместо System.Web.UI.Page

+0

@ citronas будет работать, если у меня есть несколько кнопок и несколько панелей. –

+0

Ну, это зависит от того, как вы модифицируете свой метод, чтобы заставить его работать. Я только предоставил вам информацию о том, как вы можете легко иметь такой метод на всех ваших страницах контента.Чтобы получить ссылки на эти элементы управления, вы можете рекурсивно искать их в этом. Page.Controls. – citronas

+0

Неужели мое решение не работает для вас? – citronas

0

Моя рекомендация заключалась бы в том, чтобы либо использовать главную страницу, либо разбить код на статическую функцию, которая принимает System.Web.UI.Page объект как параметр. Разумеется, вы всегда можете использовать наследование (которое будет работать), но вы потеряете возможность компоновки своей страницы с использованием функциональности времени перетаскивания, поскольку разработчик веб-форм VS.NET делает большой freakout с ASPX-страницами, которые не вытекают из System.Web.UI.Page или System.Web.UI.MasterPage напрямую.

+0

Если я правильно напомню об этом с ошибкой конструктора, то этот вопрос был VS2008 и ниже. Я не смог воспроизвести ваш сценарий с потерями функций времени разработки, так как VS2010 – citronas

+0

Вполне возможно. Я признаю, что я не создал веб-форму через некоторое время, и даже тогда, скорее всего, использовал VS2008. – Javert93

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