Tworzenie własnej kontrolki TemplateControl

by Piotrosz 31. October 2008
TemplateControl oddziela warstwę prezentacji kontrolki od danych, jakie ta kontrolka zawiera. Aby stworzyć własną TemplateControl należy:

1. Dodać do strony nową WebUserControl:



2. W pliku .ascx dodać kontrolkę PlaceHolder z ToolBoxa:



3. Nazwać PlaceHolder (tutaj PlaceHolder ma nazwę OsobaPlaceHolder):


4. W pliku code behind WebUserControl dodać właściwość ITemplate wraz z odpowiednimi atrybutami:
    private ITemplate _osobaTemplate;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateContainer(typeof(OsobaContainer))] 
    public ITemplate OsobaTemplate
    {
        get { return _osobaTemplate; }
        set { _osobaTemplate = value; }
    }
5. Dodać właściwości kontrolki reprezentujące dane (tutaj imie i nazwisko osoby):
private string _imie;
public string Imie
{
    get { return _imie; }
    set { _imie = value; }
}

private string _nazwisko;
public string Nazwisko
{
    get { return _nazwisko; }
    set { _nazwisko = value; }
}
6. Dodać kod w metodzie Page_Init:
public void Page_Init()
{
    OsobaPlaceHolder.Controls.Clear();
    if (OsobaTemplate == null)
    {
        LiteralControl lc = new LiteralControl();
        lc.Text = "";
        lc.Text += "Szablon kontrolki nie został jeszcze zdefiniowany!";
        OsobaPlaceHolder.Controls.Add(lc);
        return;
    }
    OsobaContainer s = new OsobaContainer(Imie, Nazwisko);
    OsobaTemplate.InstantiateIn(s);
    OsobaPlaceHolder.Controls.Add(s); 
}
Pełny kod w pliku code behind:
public partial class Playground_Controls_TemplatedControl : System.Web.UI.UserControl
{
    private ITemplate _osobaTemplate;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateContainer(typeof(OsobaContainer))] 
    public ITemplate OsobaTemplate
    {
        get { return _osobaTemplate; }
        set { _osobaTemplate = value; }
    }

    private string _imie;
    public string Imie
    {
        get { return _imie; }
        set { _imie = value; }
    }

    private string _nazwisko;
    public string Nazwisko
    {
        get { return _nazwisko; }
        set { _nazwisko = value; }
    }

    public void Page_Init()
    {
        OsobaPlaceHolder.Controls.Clear();
        if (OsobaTemplate == null)
        {
            OsobaPlaceHolder.Controls.Add(new LiteralControl("Szablon kontrolki nie został jeszcze zdefiniowany!"));
            return;
        }
        OsobaContainer s = new OsobaContainer(Imie, Nazwisko);
        OsobaTemplate.InstantiateIn(s);
        OsobaPlaceHolder.Controls.Add(s); 
    }    
}
7. Dodać do katalogu App_Code klasę dziedziczącą po Control i implementującą INamingContainer (tutaj to klasa o nazwie OsobaContainer):
public class OsobaContainer : Control, INamingContainer 
{
    public OsobaContainer(string imie, string nazwisko)
    {
        this._imie = imie;
        this._nazwisko = nazwisko;
    }

    private string _imie;
    public string Imie
    {
        get { return _imie; }
        set { _imie = value; }
    }

    private string _nazwisko;
    public string Nazwisko
    {
        get { return _nazwisko; }
        set { _nazwisko = value; }
    }
}

Używanie kontrolki:

Po dodaniu kontrolki na stronę (bez zdefiniowania szablonu powiwieni pokazać się komunikat zdefiniowany wcześniej w metodzie Page_Init kontrolki:




Po zdefiniowaniu szablonu i dodaniu do metody Page_Load wywołania DataBind():

 
  Imie: <%# Container.Imie %>
  
Nazwisko: <%# Container.Nazwisko %>
public void Page_Load()
{
    DataBind();
}


Zobacz wynik

HtmlEncode, HtmlDecode

by Piotrosz 29. October 2008
Przykład wyjaśniający jak działają metody HtmlEncode i HtmlDecode. Na stronie aspx jest etykieta o nazwie lbl oraz pole tekstowe o nazwie txt.

HtmlDecode, HtmlEncode Podgląd w debuggerze właściwości Text etykiety i pola tekstowego:





Wynik działania strony:

Zobacz wynik

Definiowanie własnych atrybutów

by Piotrosz 28. October 2008
Aby zdefiniować własny atrybut należy najpierw stworzyć własną klasę dziedziczącą z System.Attribute:
using System;
using System.Collections.Generic;
using System.Text;

namespace CustomAttributes
{
     // Określenie do jakich elementów można zastosować atrybut i czy można stosowac go wielokrotnie
   [AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Field | 
       AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] 
   public class CustomComment : System.Attribute 
   { 
      public CustomComment (string person, string date) 
      {  
         this.person = person; 
         this.date = date; 
      } 
       
      private string comment;
      public string Comment
      {
          get { return comment; }
          set { comment = value; }
      }

      private string date;
      public string Date
      {
          get { return date; }
      }

      private string person;
      public string Person
      {
          get { return this.person; }
      }     
  }
}
Przykład zastosowania atrybutu dla jakiejś klasy:
[CustomComment("Piotr", "2008-10-10", Comment="Pierwszy atrybut")]
    [CustomComment("Piotr", "2008-10-11", Comment="Drugi atrybut")]
    public class ClassTest
    {
    }
Wyświetlenie atrybutów dla stworzonej w programie klasy ClassTest poprzez zastosowanie refleksji:
class Program
    {
        static void Main(string[] args)
        {
            ClassTest ct = new ClassTest();
            MemberInfo minf = typeof(ClassTest);
            object [] attribs = minf.GetCustomAttributes(typeof(CustomComment), false);
            foreach (object var in attribs)
            {
                CustomComment cc = (CustomComment)var;
                Console.WriteLine(string.Format("Osoba: {0}", cc.Person));
                Console.WriteLine(string.Format("Data: {0}", cc.Date));
                Console.WriteLine(string.Format("Komentarz: {0}", cc.Comment));
            }
        }
    }
Wynik działania:

C# Custom Attributes

Odczytywanie właściwości MasterPage

by Piotrosz 21. October 2008
Aby w stronie z zawartością w łatwy sposób odwołać się do MasterPage należy:
1. Zdefiniować publiczną zmienną w klasie strony MasterPage (Tutaj jest to zmienna UlubionyOwoc).
public partial class MasterPage_MasterPage : System.Web.UI.MasterPage
{
    public string UlubionyOwoc
    {
        get { return ddlOwoce.SelectedValue; }
    }
}
Oczywiście na stronie MasterPage.master jest kontrolka DropDownList z listą owoców.

2. Na stronie, z zawartością chcemy dotać się do zmiennej zdefiniowanej w pliku MasterPage.master.cs. W tym celu dodajemy dyrektywę:
<%@ MasterType VirtualPath="~/MasterPage.master" %>


Ta dyrektywa sprawia, że właściwość klasy MasterPage jest typowana. Dodać można teraz np. taki fragment kodu:
public partial class MasterPage_AccessingMasterPageProperty : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        lbl1.Text = "W MasterPage zaznaczyłeś: " + Master.UlubionyOwoc;
    }
}

Zobacz wynik

Button - OnCommand, CommandName, CommandArgument

by Piotrosz 18. October 2008
Kod w pliku .aspx:



Przywitaj się oficjalnie Przywitaj się nieoficjalnie
Kod w pliku .cs:
public partial class CommandButtonTest : System.Web.UI.Page
{
    protected void WykonanieKomendy(object sender, CommandEventArgs e)
    {
        switch (e.CommandName)
        {
            case "PokazDateCzas" :
                switch (e.CommandArgument.ToString())
                {
                    case "Data" :
                        Label1.Text = string.Format("Data: {0}", DateTime.Now.ToString("yyyy-MM-dd"));
                        break;
                    case "Czas" :
                        Label1.Text = string.Format("Czas: {0}", DateTime.Now.ToString("HH:mm:ss"));
                        break;
                    default:
                        break;
                }
                break;
            case "PrzywitajSie" :
                switch (e.CommandArgument.ToString())
                {
                    case "Oficjalnie" :
                        Label1.Text = "Dzień dobry";
                        break;
                    case "Nieoficjalnie" :
                        Label1.Text = "Cześć";
                        break;
                    default :
                        break;
                }
                break;
            default :
                break;    
        }
    }
}

Zobacz wynik
UPDATE: Przekazanie numeru wiersza GridView do metody GridView_RowCommand:

                    
      
    

Dynamiczne dodawanie kontrolek na stronie aspx

by Piotrosz 17. October 2008
Dynamiczne dodawanie kontrolek serwera (web server controls) w metodzie Page_Init:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Init(object sender, EventArgs e)
    {
        Label lbl1 = new Label();
        lbl1.ID = "lbl1";
        lbl1.Text = "Dynamicznie dodana etykieta <br/>";
        lbl1.BackColor = System.Drawing.Color.Red;
        lbl1.ForeColor = System.Drawing.Color.White;
        lbl1.Visible = true;
        form1.Controls.Add(lbl1);

        TextBox txt1 = new TextBox();
        txt1.ID = "txt1";
        txt1.Width = 300;
        txt1.Visible = true;
        form1.Controls.Add(txt1);
    }
}
Wynik działania po wyświetleniu strony:
Adding web server controls dynamically via C# code

Zobacz wynik

Do umiejscowienia dynamicznie dodanych kontrolek można wykorzystać kontrolkę PlaceHolder:

Drugi przykład który uwzględnia także dynamiczne tworzenie kodu html przy użyciu kontrolki LiteralControl i stworzenie UpdatePanel:
PlaceHolder1.Controls.Add(new LiteralControl("<table><tr><td>"));

TextBox txt = new TextBox();
txt.ID = "txt1";
txt.Text = "Hello";

PlaceHolder1.Controls.Add(txt);
PlaceHolder1.Controls.Add(new LiteralControl("</td></tr></table>"));
Jeszcze jedna uwaga. Po PostBacku dynamicznie dodane kontrolki są usuwane z pamięci. Trzeba je więc tworzyć w metodzie Page_Init lub PagePreInit niezależnie od wartości właściwości Page.IsPostBack.

Dynamiczne zapytanie SQL w procedurze składowanej

by Piotrosz 16. October 2008
Przykład procedury składowanej, która dynamicznie tworzy zapytanie SQL. Zapytanie wykonywane jest za pomocą polecenia EXEC:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE sp_SelectPeople
	@FirstName varchar(20)
	@LastName varchar(100)
	@Status varchar(20)
AS
BEGIN
	SET NOCOUNT ON;
	DECLARE @WhereClause varchar(250)

	SET @WhereClause = 'WHERE 1=1 ' 	

	IF @FirstName <> ''
		SET @WhereClause = @WhereClause + ' AND FirstName =''' + @FirstName + '''' 
	IF @LastName <> ''
		SET @WhereClause = @WhereClause + ' AND LastName = ''' + @LastName + ''''
	IF @Status <> ''
		SET @WhereClause = @WhereClause  + ' AND Status IN (' @Status + ')'

	DECLARE @sqlQuery varchar(550)
	SET @sqlQuery = 'SELECT [FirstName], [LastName], [Status] FROM [People] '
	SET @sqlQuery = @sqlQuery + @WhereClause
	
	-- Aby Visual Studio zserializował kolumny w TableAdapterze
        -- Dzięki temu będzie można używać "typed DataSet"
	-- SELECT FirstName, LastName, Status FROM [People] WHERE id = -1

	-- Takie wykonanie jest niebezpieczne ze względu na możliwość ataku SQL injection
	--EXEC(@sqlQuery);

	EXEC sp_executesql @sqlQuery, N'@FirstName varchar(20),@LastName varchar(100),
@Status varchar(20)',@FirstName,@LastName,@Status
END
GO

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen