Nie jestem guru w składni maszyn Razor, ale staram się zbudować ogólną bibliotekę za pomocą płynnych elementów interfejsu GUI Telerik.Razor Func <obiekt, obiekt> zmieszany z MvcHtmlString
Mam następujące kawałki (w przybliżeniu):
public static MyBox Box(this HtmlHelper helper)
{
return new MyBox(helper.ViewContext);
}
oraz:
/// <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 -->");
}
}
Mam też zestaw HTML metod rozszerzenie, które zwracają MvcHtmlString jest. Jednym z przykładów jest (uproszczony):
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));
}
}
Następnie w moim .cshtml pliku, I wykonaj następujące czynności:
@using (Html.BeginForm())
{
@(Html.Gui()
.Box()
.Title("Hello World!")
.Content(
@<h1>Hello World! This is the cool Gui.Box</h1>
)
)
}
który wzywa public MyBox Content(Func<object, object> value)
, i działa. Podobnie, gdy próbuję następujące:
@using (Html.BeginForm())
{
@(Html.Gui()
.Box()
.Title("Hello World!")
.Content(
Html.GuiFieldContainerHeading("SubHeading 1")
)
)
}
To szczęśliwie nazywa public MyBox Content(MvcHtmlString content)
i działa zgodnie z oczekiwaniami.
Jednak, gdy próbuję wykonać następujące czynności, nie mogę objąć głowy, jak działa silnik kompilatora Razor. Jak mogę zmusić go do powrotu sumę
@<h1>Hello World! This is Gui().Box()</h1>
(co jest Func)Html.GuiFieldContainerHeading("SubHeading 1")
(który jest MvcHtmlString)
albo jako jeden obiekt (czy to Func, MvcHtmlString ?, niezależnie, czy lista obiektów chciałbym napisać rodzajowy składni Razor wewnątrz listy parametrów do funkcji Content w mojej klasie myBOX, tak:
@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>
)
)
}
Czy jestem na dobrej drodze, czy też jest o wiele prostszy sposób robienia tego, co chcę? Chcę zebrać wszystkie "wspólne elementy GUI" w naszym systemie we wspólnej bibliotece DLL, więc nie każdy programista w mojej organizacji musi wymyślić nowe koło w każdym projekcie.
Każda pomoc doceniona.
OK, kolejnym problemem:
Mam uogólnione Box do pojemnika i stworzył dwie podklasy, pudełko i HighlightArea. Jednakże, używając następującego kodu, kompilator Razor wykopuje mnie z wiadomością
bloki Inline znaczników (@ <p> Content </p >) nie mogą być zagnieżdżone. Dozwolony jest tylko jeden poziom wbudowanych znaczników.
Kod nie działa, to:
@(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>
)
Czy mamy obejście tego? Czy moje podejście jest niewykonalne?
Twój przykład zawierający 'This is Gui(). Box()' jest nieco mylący. Wygląda na to, że zawiera jakiś kod C#, ale prawdopodobnie nie powinien. – Codo
Dzięki. Zaktualizowałem to pytanie, aby uniknąć konfrontacji. Jakieś myśli na temat inne niż zamieszanie? –
Następny problem (dzięki, Bill The Lizard, za aktualizację pytania ...:)) ... Wszelkie przemyślenia na ten temat (patrz pytanie) –