ASP.NET sterowanie niestandardowe-Composites

Podsumowanie

Cześć Wszystkim,
Ok, dalej w moich przygodach z niestandardowym sterowaniem...

Podsumowując, oto, że nauczyłem się trzech głównych "klas" niestandardowych kontroli. Proszę, popraw mnie, jeśli coś z tego jest złe!

  1. UserControls - które dziedziczą z UserControl i są zawarte w pliku ASCX . Są one dość ograniczone w tym, co mogą zrobić, ale są szybkim i lekkim sposobem na uzyskanie wspólnego interfejsu użytkownika z wsparcie projektanta.
  2. Custom Composite Controls - są to kontrolki dziedziczone z WebControl , gdzie dodajemy istniejące kontrolki do kontrolki w metodzie CreateChildControls . Zapewnia to dużą elastyczność, ale brak wsparcia projektanta bez dodatkowego kodowania. Są one bardzo przenośne, ponieważ mogą być skompilowane w DLL.
  3. Custom Rendered Controls - podobne do Custom Composite Controls, są one dodawane do projekt webowej Biblioteki sterowania. Renderowanie kontrolki jest całkowicie kontrolowane przez programistę poprzez nadpisanie metody Render.

Moje Myśli..

OK, więc grając z niestandardowych kompozytów, znalazłem następujące:

  • masz małą / brak kontroli nad wyjściem HTML, co utrudnia "debugowanie".
  • CreateChildControls (i kolejne metody) mogą być naprawdę zajęte kontrolkami .Add (myControl) wszędzie.
  • uznałem, że renderowanie tabel (czy to dla układu, czy treści) jest znacznie niezręczne.

Pytanie (y)..

Więc, przyznaję, jestem w tym nowy, więc mogę być daleko od podstaw z niektórych moich punktów wymienionych powyżej..

  • czy używasz kompozytów?
  • Czy masz jakieś fajne sztuczki, aby kontrolować wyjście HTML?
  • czy po prostu powiesz "do diabła z tym" i śmiało stwórz niestandardową kontrolę?

Its something I am keen aby być naprawdę stanowczym w moim umyśle, ponieważ Wiem, jak bardzo dobry rozwój kontroli może skrócić ogólny czas rozwoju.

Czekam na Wasze odpowiedzi ^_^

Author: Rob Cooper, 2008-08-20

6 answers

Mówię śmiało z custom rendered control. Uważam, że w większości przypadków kompozyt można łatwiej zrobić i wykorzystać w UserControl, ale cokolwiek poza tym i trzeba mieć drobniejszy stopień kontroli (Kalambury), aby zasłużyć na własną strategię renderowania.

Być może istnieją kontrolki, które są wystarczająco proste, aby zasługiwać na kompozyt (np. pole tekstowe połączone z datepickerem opartym na javascript/dhtml), ale poza tym jednym przykładem, wygląda to jak niestandardowe renderowane kontrolki to jest droga.

 5
Author: Jon Limjap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 07:53:32

Oto kolejna metoda rozszerzenia, której używam do niestandardowego renderowania:

 public static void WriteControls
        (this HtmlTextWriter o, string format, params object[] args)
 { 
    const string delimiter = "<2E01A260-BD39-47d0-8C5E-0DF814FDF9DC>";
    var controls  = new Dictionary<string,Control>();

    for(int i =0; i < args.Length; ++i)
    { 
       var c = args[i] as Control; 
       if (c==null) continue;
       var guid = Guid.NewGuid().ToString();
       controls[guid] = c;
       args[i] = delimiter+guid+delimiter;
    }

    var _strings = string.Format(format, args)
                         .Split(new string[]{delimiter},
                                StringSplitOptions.None);
    foreach(var s in _strings)
    { 
       if (controls.ContainsKey(s)) 
           controls[s].RenderControl(o);
       else 
           o.Write(s);
    }
}

Następnie, aby renderować Niestandardowy kompozyt w metodzie RenderContents () piszę tak:

protected override void RenderContents(HtmlTextWriter o)
{ 
    o.WriteControls
         (@"<table>
               <tr>
                    <td>{0}</td>
                    <td>{1}</td>
               </tr>
             </table>"
            ,Text
            ,control1);
 }
 3
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 15:22:37

Rob, masz rację. Podejście, o którym wspomniałem, jest rodzajem hybrydy. Zaletą posiadania plików ascx jest to, że w każdym projekcie, który widziałem, projektanci czuliby się najbardziej komfortowo z edytowaniem rzeczywistych znaczników, a z ascx ty i projektant możecie pracować osobno. Jeśli później nie planujesz rzeczywistych zmian CSS/znaczników / projektu w samych kontrolkach, możesz skorzystać z niestandardowej renderowanej kontrolki. Jak powiedziałem, moje podejście jest istotne tylko dla bardziej skomplikowanych scenariuszy (a są to prawdopodobnie tam, gdzie potrzebujesz projektanta :))

 2
Author: Slavo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 19:44:35

Często używam sterowania kompozytowego. Zamiast nadpisywać render lub Rendercontenty, po prostu Przypisz każdej kontroli klasę CssClass i użyj arkuszy stylów. Do wielu kontroli.Dodaj, używam metody rozszerzenia:

//Controls.Add(c1, c2, c3)
static void Add(this ControlCollection coll, params Control[] controls)
 { foreach(Control control in controls) coll.Add(control);
 }

Do szybkiego i brudnego renderowania używam czegoś takiego:

writer.Render(@"<table>
                   <tr><td>{0}</td></tr>
                   <tr>
                       <td>", Text);
control1.RenderControl(writer);
writer.Render("</td></tr></table>");

Do inicjalizacji właściwości sterowania używam składni property initializer:

childControl = new Control {  ID="Foo"
                            , CssClass="class1"
                            , CausesValidation=true;
                           };
 1
Author: Mark Cidade,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 08:02:18

Używanie niestandardowych formantów kompozytowych ma punkt w sytuacji, gdy masz dużą aplikację internetową i chcesz ponownie użyć dużych kawałków w wielu miejscach. Następnie dodałbyś tylko kontrolki potomne tych, które rozwijasz, zamiast powtarzać się. Nad dużym projektem pracowałem ostatnio, co zrobiliśmy jest następujące:

  • każda kontrola złożona ma kontener. Używany jako owinięty do wszystkiego wewnątrz sterowania.
  • każda kontrola złożona ma szablon. Plik ascx (bez dyrektywy ), która zawiera tylko znaczniki dla szablonu.
  • kontener (będący kontrolką samą w sobie) jest inicjowany z szablonu.
  • kontener eksponuje właściwości dla wszystkich innych kontrolek w szablonie.
  • Używasz tylko tego.Sterowanie.Dodaj ([the_container]) do kontrolki złożonej.

W rzeczywistości potrzebujesz klasy bazowej, która zajmie się inicjalizacją kontenera z podanym szablonem, a także wyrzuceniem WYJĄTKÓW, gdy Kontrola nie znajduje się w szablonie. Oczywiście może to być przesada w małej aplikacji. Jeśli nie używasz ponownie kodu i znaczników, a chcesz pisać tylko proste kontrolki, lepiej Użyj kontrolek użytkownika.

 1
Author: Slavo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-20 10:27:56

Być może będziesz w stanie wykorzystać tę technikę, aby ułatwić projektowanie:

Http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx

Zasadniczo tworzysz instancję kontrolki użytkownika w czasie wykonywania przy użyciu metody LoadControl, następnie przekazujesz jej jakiś pasek stanu, a następnie dołączasz go do drzewa kontrolek. Więc twoje złożone sterowanie faktycznie będzie działać jak bardziej kontroler, i .plik ascx byłby jak widok.

Zaoszczędzi ci to kłopotu z koniecznością tworzenia instancji całego drzewa kontrolek i stylizacji ich w C#!

 0
Author: Andrew Myhre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 11:20:20