I have a Scheduler:
我有一个调度程序:
@(Html.Kendo().Scheduler<HTServices.Models.TaskViewModel>()
.Name("scheduler")
.Date(DateTime.Now)
.StartTime(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 7, 00, 00))
.Height(600)
.Editable(edit =>
{
edit.TemplateName("ScheduleItemTemplate");
edit.Create(false);
edit.Destroy(false);
})
.Views(views =>
{
views.DayView();
views.WeekView(workWeekView => workWeekView.Selected(true));
views.MonthView();
views.AgendaView();
})
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.TaskID);
m.Field(f => f.Title).DefaultValue("No title");
m.Field(f => f.OwnerID).DefaultValue(1);
m.Field(f => f.Title).DefaultValue("No title");
m.RecurrenceId(f => f.RecurrenceID);
})
.Read("Read", "Scheduler")
.Create("Create", "Scheduler")
.Destroy("Destroy", "Scheduler")
.Update("Update", "Scheduler")
)
)
It loads great with my custom template.
它装载了我的自定义模板。
@model HTServices.Models.TaskViewModel
@{
//required in order to render validation attributes
ViewContext.FormContext = new FormContext();
}
@functions{
}
<div class="k-edit-label">
@(Html.LabelFor(model => model.Client))
</div>
<div data-container-for="client" class="k-edit-field">
@(Html.TextBoxFor(model => model.Client, new { style = "width:100%;", @readonly = "readonly", @class = "k-textbox col-lg-12", data_bind = "text: client" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.Address))
</div>
<div data-container-for="address" class="k-edit-field">
@(Html.TextBoxFor(model => model.Address, new { style = "width:100%;", @readonly = "readonly", @class = "k-textbox", data_bind = "text: address" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.Start))
</div>
<div data-container-for="start" class="k-edit-field">
@(Html.TextBoxFor(model => model.Start, new { style = "width:100%;", @class = "k-textbox", @readonly = "readonly", data_bind = "value: start" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.End))
</div>
<div data-container-for="end" class="k-edit-field">
@(Html.TextBoxFor(model => model.End, new { style = "width:100%;", @class = "k-textbox", @readonly = "readonly", data_bind = "value: end" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.IsAllDay))
</div>
<div data-container-for="isAllDay" class="k-edit-field">
@(Html.DisplayFor(model => model.IsAllDay, new { @class = "k-checkbox", @readonly = "readonly", data_bind = "value: isAllDay" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.Description))
</div>
<div data-container-for="description" class="k-edit-field">
@(Html.TextAreaFor(model => model.Description, new { @class = "k-textbox", @readonly = "readonly", data_bind = "value: description" }))
</div>
<div class="k-edit-label">
@(Html.LabelFor(model => model.DutyID))
</div>
<div data-container-for="duties" data-task-id="@Model.TaskID" class="k-edit-field">
</div>
@{
ViewContext.FormContext = null;
}
and then I add a PanelBar with binding to a hierarchical model... yes it's supposed to be possible:
然后我添加了一个带有绑定到层次模型的PanelBar…是的,它应该是可能的:
see link for hierarchical model binding:
层次模型绑定见链接:
(Html.Kendo().PanelBar()
.Name("dutyPanel")
.ExpandMode(PanelBarExpandMode.Single)
.BindTo(Model.Duties, mappings =>
{
mappings.For<PanelGroup>(binding => binding //define first level of panelbar
.ItemDataBound((item, dutygrp) => //define mapping between panelbar item properties and the model properties
{
item.Text = dutygrp.Text;
item.ImageUrl = dutygrp.ImageUrl;
})
.Children(dutygrp => dutygrp.Items)); //define which property of the model contains the children
mappings.For<PanelGroupItem>(binding => binding
.ItemDataBound((item, duty) =>
{
item.Text = duty.Text;
item.ImageUrl = duty.ImageUrl;
}));
})
But then, when I run the app, and navigate to the page, before the Index action for the controller even fires, I get a:
但是,当我运行应用程序,导航到页面时,在控制器的索引操作甚至发生火灾之前,我得到一个:
System.NullReferenceException was unhandled by user code
系统。NullReferenceException未被用户代码处理
HResult=-2147467261
HResult = -2147467261
Message=Object reference not set to an instance of an object.
消息=对象引用,未设置为对象的实例。
Source=Kendo.Mvc
源= Kendo.Mvc
The line :
线:
.BindTo(Model.Duties, mappings =>
Shows that Duties, a model member, is null. Yeah, no kidding it's null... The Action from the controller wasn't even hit yet.
显示职责(模型成员)为空。是啊,别开玩笑了,这是无效的……控制器的动作还没有被击中。
I guess this is a bug?
我猜这是一个bug?
1 个解决方案
#1
0
I got it working with javascript binding - and didn't use the MVC version.
我让它与javascript绑定一起工作,并且没有使用MVC版本。
My Panel... (tadaaaa)
我的小组…(tadaaaa)
<div id="dutyPanel"></div>
my javascript to load panel when scheduler item edits:
我的javascript加载面板时,调度项目编辑:
$(function () {
////bind to the scheduler edit event
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.bind("edit", onSchedulerEdit);
function onSelect(e) {
e.preventDefault();
}
function onSchedulerEdit(e) {
var d = e.event.Duties;
$("#dutyPanel").kendoPanelBar({
expandMode: "multiple",
select: onSelect,
dataSource: jQuery.makeArray(d)
});
};
});
the data object I use to fill from the DB.... (controller Read function - get all 'duties' for each item in schedule all at once)
我使用的数据对象从DB ....填补(控制器读取功能-一次性获取每个项目的所有“职责”)
public class PanelItem
{
public string text { get; set; }
public string cssClass { get; set; } // Add custom CSS class to the item, optional
public string url { get; set; } // link url for navigation to topic if required, optional
public string imageUrl { get; set; } // item image URL, optional
public string spriteCssClass { get; set; } // item image sprite CSS class, optional
public string contentUrl { get; set; } // content URL to load within an item, optional
public bool expanded { get; set; } // item is rendered expanded, optional
}
public class PanelGroup : PanelItem
{
public List<PanelItem> items { get; set; } // Sub item collection
}
So, see back in javascript? The 'Duties' member in the Event is of type PanelGroup
回头看看javascript?事件中的“职责”成员是类型PanelGroup
Oh! You want to indent panel bar items?
哦!你想缩进面板栏项目?
In my ScheduleItemTemplate.cshtml - add the styles there:
在我ScheduleItemTemplate。cshtml -在那里添加样式:
<style type="text/css">
.panelbarHeader {
font-size: 1em;
font-weight: normal;
}
.panelbarItem {
text-decoration: none;
font-size: .9em;
font-weight: normal;
padding-left: 20px;
}
</style>
When filling the PanelGroup object from DB, set the cssClass there:
当从DB中填充PanelGroup对象时,在那里设置cssClass:
List<DB_Result_Object> results = db.Database.SqlQuery<DB_Result_Object>(commandSQL, strParams.ToArray()).ToList();
List<TaskViewModel> result = results.ToList().Select(item => new TaskViewModel
{
TaskID = item.CalendarAppointmentID,
Title = item.FieldSuitableForTitleShow),
Start = item.CalendarAppointmentDateStart,
End = item.CalendarAppointmentDateEnd,
StartTimezone = null,
EndTimezone = null,
Description = item.CalendarAppointmentDetail.StripMarkup(), // yeah - a string extension method...
IsAllDay = (item.CalendarAppointmentIsAllDayEvent > 0),
RecurrenceRule = null,
RecurrenceException = null,
RecurrenceID = null,
OwnerID = item.TheGuysID,
Duties = GetDuties(item.PrimaryID) // another function to get the duties...
}).ToList();
return result.AsQueryable();
And in the GetCalendarDuties:
和GetCalendarDuties:
List<PanelGroup> panels = new List<PanelGroup>();
The usual DB stuff... and then...
通常的DB的东西……然后……
spin through the results...and for each new group...however you determine yours...
旋转的结果……对于每一个新群体……但是你确定你…
pg = new PanelGroup() { text = ThisGroupName, cssClass = "panelbarHeader", imageUrl = string.Format("Content/scheduler/img/{0}.png", imageNameForGroup), items = new List<PanelItem>() };
panels.Add(pg);
and for each new item - however you determine yours...
对于每一个新项目——无论你如何决定你的……
pg.items.Add(new PanelItem { text = ThisItemName, cssClass = "panelbarItem", imageUrl = string.Format("Content/scheduler/img/{0}.png", imageNameForItem) });
Voila...panelbar in scheduler item template.
瞧……调度程序项模板中的panelbar。
#1
0
I got it working with javascript binding - and didn't use the MVC version.
我让它与javascript绑定一起工作,并且没有使用MVC版本。
My Panel... (tadaaaa)
我的小组…(tadaaaa)
<div id="dutyPanel"></div>
my javascript to load panel when scheduler item edits:
我的javascript加载面板时,调度项目编辑:
$(function () {
////bind to the scheduler edit event
var scheduler = $("#scheduler").data("kendoScheduler");
scheduler.bind("edit", onSchedulerEdit);
function onSelect(e) {
e.preventDefault();
}
function onSchedulerEdit(e) {
var d = e.event.Duties;
$("#dutyPanel").kendoPanelBar({
expandMode: "multiple",
select: onSelect,
dataSource: jQuery.makeArray(d)
});
};
});
the data object I use to fill from the DB.... (controller Read function - get all 'duties' for each item in schedule all at once)
我使用的数据对象从DB ....填补(控制器读取功能-一次性获取每个项目的所有“职责”)
public class PanelItem
{
public string text { get; set; }
public string cssClass { get; set; } // Add custom CSS class to the item, optional
public string url { get; set; } // link url for navigation to topic if required, optional
public string imageUrl { get; set; } // item image URL, optional
public string spriteCssClass { get; set; } // item image sprite CSS class, optional
public string contentUrl { get; set; } // content URL to load within an item, optional
public bool expanded { get; set; } // item is rendered expanded, optional
}
public class PanelGroup : PanelItem
{
public List<PanelItem> items { get; set; } // Sub item collection
}
So, see back in javascript? The 'Duties' member in the Event is of type PanelGroup
回头看看javascript?事件中的“职责”成员是类型PanelGroup
Oh! You want to indent panel bar items?
哦!你想缩进面板栏项目?
In my ScheduleItemTemplate.cshtml - add the styles there:
在我ScheduleItemTemplate。cshtml -在那里添加样式:
<style type="text/css">
.panelbarHeader {
font-size: 1em;
font-weight: normal;
}
.panelbarItem {
text-decoration: none;
font-size: .9em;
font-weight: normal;
padding-left: 20px;
}
</style>
When filling the PanelGroup object from DB, set the cssClass there:
当从DB中填充PanelGroup对象时,在那里设置cssClass:
List<DB_Result_Object> results = db.Database.SqlQuery<DB_Result_Object>(commandSQL, strParams.ToArray()).ToList();
List<TaskViewModel> result = results.ToList().Select(item => new TaskViewModel
{
TaskID = item.CalendarAppointmentID,
Title = item.FieldSuitableForTitleShow),
Start = item.CalendarAppointmentDateStart,
End = item.CalendarAppointmentDateEnd,
StartTimezone = null,
EndTimezone = null,
Description = item.CalendarAppointmentDetail.StripMarkup(), // yeah - a string extension method...
IsAllDay = (item.CalendarAppointmentIsAllDayEvent > 0),
RecurrenceRule = null,
RecurrenceException = null,
RecurrenceID = null,
OwnerID = item.TheGuysID,
Duties = GetDuties(item.PrimaryID) // another function to get the duties...
}).ToList();
return result.AsQueryable();
And in the GetCalendarDuties:
和GetCalendarDuties:
List<PanelGroup> panels = new List<PanelGroup>();
The usual DB stuff... and then...
通常的DB的东西……然后……
spin through the results...and for each new group...however you determine yours...
旋转的结果……对于每一个新群体……但是你确定你…
pg = new PanelGroup() { text = ThisGroupName, cssClass = "panelbarHeader", imageUrl = string.Format("Content/scheduler/img/{0}.png", imageNameForGroup), items = new List<PanelItem>() };
panels.Add(pg);
and for each new item - however you determine yours...
对于每一个新项目——无论你如何决定你的……
pg.items.Add(new PanelItem { text = ThisItemName, cssClass = "panelbarItem", imageUrl = string.Format("Content/scheduler/img/{0}.png", imageNameForItem) });
Voila...panelbar in scheduler item template.
瞧……调度程序项模板中的panelbar。