2011-09-21 37 views
7

Razor sözdiziminde guru yapıyorum, ancak akıcı bir stil olan Telerik'in GUI bileşenlerini kullanarak bir genel kitaplık oluşturmaya çalışıyorum.Razor Func <object, object> MvcHtmlString ile karıştırıldı

public static MyBox Box(this HtmlHelper helper) 
{ 
    return new MyBox(helper.ViewContext); 
} 

ve:

/// <summary> 
/// http://geekswithblogs.net/shaunxu/archive/2010/04/10/lt-gt-htmlencode-ihtmlstring-and-mvchtmlstring.aspx 
/// </summary> 
public class MyBox : IHtmlString 
{ 
    private readonly ViewContext _viewContext; 
    private string _content; 
    private string _title; 

    public MyBox(ViewContext viewViewContext) 
    { 
     _viewContext = viewViewContext; 
    } 

    /// <summary> 
    /// See: http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx 
    /// </summary> 
    /// <param name="value"></param> 
    /// <returns></returns> 
    public MyBox Content(Func<object, object> value) 
    { 
     _content = value.DynamicInvoke(_viewContext).ToString(); 
     return this; 
    } 

    /// <summary> 
    /// See: http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx 
    /// </summary> 
    /// <param name="values"></param> 
    /// <returns></returns> 
    public MyBox Content(params Func<object, object>[] values) 
    { 
     foreach (var value in values) 
     { 
      _content += value.DynamicInvoke(_viewContext).ToString(); 
     } 
     return this; 
    } 

    public MyBox Content(MvcHtmlString content) 
    { 
     _content = content.ToString(); 
     return this; 
    } 

    public MyBox Title(string title) 
    { 
     _title = title; 
     return this; 
    } 

    public string ToHtmlString() 
    { 
     using (var stringWriter = new StringWriter()) 
     { 
      WriteHtml((TextWriter)stringWriter); 
      return stringWriter.ToString(); 
     } 
    } 

    public void Render() 
    { 
     using (var writer = new HtmlTextWriter(_viewContext.Writer)) 
      WriteHtml(writer); 
    } 

    protected virtual void WriteHtml(TextWriter writer) 
    { 
     writer.WriteLine("<!-- START BOX -->"); 
     writer.WriteLine("<h1>" + _title + "</h1>)); 
     writer.WriteLine(_content); 
     writer.WriteLine("<!-- END BOX -->"); 
    } 
} 

Ayrıca MvcHtmlString en geri HTML uzantısı yöntemleri bir dizi var

I (yaklaşık), aşağıdaki parçaları vardır. Bir örnek (basitleştirilmiş) olduğu:

public static class GuiElementExtensions 
    { 
     private const string FieldContainerHeadingTemplate = @" 
<tr><th style=""text-align:left"" colspan=""2"">{0}</th></tr> 
"; 

    public static MvcHtmlString GuiFieldContainerHeading(this HtmlHelper helper, string text) 
     { 
      return new MvcHtmlString(String.Format(FieldContainerHeadingTemplate, text)); 
     } 
} 

Sonra benim .cshtml dosyasında, ben aşağıdakileri yapın:

public MyBox Content(Func<object, object> value) çağırır ve eserleri
@using (Html.BeginForm()) 
     { 
      @(Html.Gui() 
         .Box() 
         .Title("Hello World!") 
         .Content(
           @<h1>Hello World! This is the cool Gui.Box</h1> 
         ) 
     ) 
} 

. Benzer şekilde, aşağıdaki çalıştığınızda: Bu mutlu public MyBox Content(MvcHtmlString content) çağırır ve beklendiği gibi çalıştığını

@using (Html.BeginForm()) 
     { 
      @(Html.Gui() 
         .Box() 
         .Title("Hello World!") 
         .Content(
           Html.GuiFieldContainerHeading("SubHeading 1") 
         ) 
     ) 
} 

. Ancak, aşağıdakileri yapmaya çalıştığımda, Razor derleyici motorunun nasıl çalıştığını kafamın üzerine koyamıyorum. Bunu nasıl ya bir nesne olarak (bir MvcHtmlString olan) (a Func olan)

  • @<h1>Hello World! This is Gui().Box()</h1> toplamını
  • Html.GuiFieldContainerHeading("SubHeading 1")

dönmek alabilirim (bir Func, MvcHtmlString olmak ?, ne olursa olsun, ya da nesnelerin bir listesi böyle, benim MyBox sınıfında İçerik işlevine argüman listesinde jenerik Jilet sözdizimi yazmak istiyorum:

@using (Html.BeginForm()) 
     { 
      @(Html.Gui() 
         .Box() 
         .Title("Hello World!") 
         .Content(
           @<h1>Hello World! This is Gui().Box()</h1> 
           Html.GuiFieldContainerHeading("SubHeading 1") 
       Html.TextBoxFor(model => model.Name) 
       @<h2>Hello there!</h2> 
         ) 
     ) 
} 

Doğru yolda mıyım, yoksa istediğimi yapmanın daha basit bir yolu var mı? Sistemimizdeki tüm "ortak gui unsurlarını" ortak bir DLL'de toplamak istiyorum, bu yüzden organizasyonumdaki her geliştiricinin her bir projede tekerleği yeniden icat etmesi gerekmiyor.

Herhangi bir yardım için teşekkür ederiz.


Tamam, bir sonraki sorun:

Bir Konteyner içine Kutusu genelleştirilmiş ve iki alt sınıfa Kutusu ve HighlightArea oluşturduk. Ancak, aşağıdaki kodu kullanarak, Jilet derleyici

Inline biçimlendirme blokları (<p> İçerik </p > @) iç içe olamaz mesajla beni başladı. Sadece tek bir satır içi işaretlemeye izin verilir.

kod çalışmıyor vardır:

@(Html.Gui() 
       .Box() 
       .Title("BoxTitle") 
       .Content(@<text> 
         <h1>Hello World! This is the box content</h1> 
         @Html.GuiFieldContainerHeading("This is the heading") 
         @(Html.Gui().HighlightArea() 
           .Content(
           @Html.ValidationSummary() 
           @<h1>Jalla</h1> 
          ) 
         ) 
         </text> 
       ) 

bunun için bir çözüm var mı? Yoksa benim yaklaşımım uygun değil mi?

+1

Örneğiniz 'Bu, Gui()' dir. Kutu() 'biraz kafa karıştırıcı. Bazı C# kodu içeriyor gibi görünüyor ama muhtemelen olması gerekiyordu. – Codo

+0

Teşekkürler. Herhangi bir konfeksiyondan kaçınmak için soruyu güncelledim. Bu karışıklık dışındaki soru üzerine herhangi bir düşünce? –

+0

Sonraki sorun (teşekkürler, Bill Kertenkele, soruyu güncellemek için ...:)) ... Bunun üzerine herhangi bir düşünce (soruya bakın) –

cevap

7

Her şeyi tek bir parametrede birleştirmek için <text> etiketini kullanabilirsiniz.

@using (Html.BeginForm()) 
{ 
    @(Html.Gui() 
     .Box() 
     .Title("Hello World!") 
     .Content(
      @<text> 
       <h1>Hello World! This is Gui.Box</h1> 
       @Html.GuiFieldContainerHeading("SubHeading 1") 
       @Html.TextBoxFor(model => model.Name) 
       <h2>Hello there!</h2> 
      </text> 
     ) 
    ) 
} 

Ben senin örnek gerçekten çalışmıyor sanırım. Yanılmıyorsam eğer böyle çalışır duruma alabilir:

@<h1>Hello World! This is Gui.Box</h1> 
+ Html.GuiFieldContainerHeading("SubHeading 1") 
+ Html.TextBoxFor(model => model.Name) 
+ @<h2>Hello there!</h2> 

Ama <text> etiket daha kolay görünüyor.

+0

Bir çekicilik gibi çalıştım. Teşekkürler! :) –