telerik学习总结
2016-05-30 15:54
323 查看
Telerik
Telerik 是保加利亚的一个软件公司,专注于微软.Net平台的表示层与内容管理控件。Telerik 提供高度稳定性和丰富性能的组件产品,并可应用在非常严格的环境中。现在 拥有 Microsoft, HP, Alcoa, BP, Harper Collins,
Siemens, T-Mobile, HJ Heinz和一些最主要的教育机构和很多政府机关等客户。
telerik 的 r.a.d.controls 套装是一款最具革命性和广泛性的开发工具集,它主要针对专业级的 ASP.NET
开发,适用于 AJAX, Atlas 、Visual Studio .NET 2005 、Visual Studio 2008 及 ASP.NET 3.5。通过该产品的
强大功能,开发者可以开发出功能丰富、适应标准广泛,与交互浏览器兼容的网络应用程序。
2012年,Telerik新推出了Icenium服务,该服务是一个集成的云环境(Integrated Cloud Enviroment,ICE
)。
数十年来,IDE一直是应用开发的基础,微软Visual Studio,Eclipse、NetBeans等都是IDE的代表。IDE的
问题是开发和部署有许多繁琐的要求,在环境和客户端种类繁多的移动时代已经显得支撑不足。
针对IDE的这些弊端,Icenium把所有移动应用开发都搬到了云上面,把IDE中的SDK、编译器、测试、调试、
数字认证等,通通都变成了云服务,这样的话开发者就可以在任何设备、任何开发环境上开发应用,从而摆脱物理
环境或特定平台的束缚。
Icenium具有一次开发、支持多种部署的能力。该服务可通过浏览器访问,用户可运用其HTML5、CSS及
JavaScript技能来创建部署应用,所创建的原生应用可以在苹果iOS平台和Google Android平台运行。
在Icenium中,开发者可利用Apache Cordova开发具备拍照、加速计、定位等功能的混合型应用。可访问
GitHub等给予URL的Git容器。集成的版本控制允许保存代码,并在云端进行版本化,从而可以在任何时间任何地方
访问这些代码。
cenium还有一个集成的模拟环境,让开发者无需部署就可以看到应用在设备端的样子。Icenium还允许开发
者了解应用在不同外形因素下的样子。开发者可以在数分钟之内实现传统方法需要半小时或更多的时间才能完成的
事情。
与Icenium类似的服务还有PhoneGap和Kii Cloud。这些服务降低了开发复杂性,加快了开发速度,对IDE缺
乏深入了解的开发者以及希望加速应用部署及有效管理开发的企业来说都具有很大的吸引力。
Icenium于去年夏天开始进行不公开beta测试,现在已经开放公测至明年5月份,有兴趣的同学不妨到其网站
试试。
========
Telerik控件使用
方法/步骤1
RadGrid添加序号列
<telerik:GridTemplateColumn HeaderText="序号列">
<ItemTemplate> <%#System.Convert.ToInt32(DataBinder.Eval
(Container,"ItemIndex"))+1 %>
</ItemTemplate>
</telerik:GridTemplateColumn>
2
telerik:RadWindow 弹出窗口
<telerik:RadWindowManager>→<Windows>→<telerik:RadWindow>→ <ContentTemplate>
a.AutoSize:自适应大小
b.ReloadOnShow:
c.ShowContentDuringLoad:
d.VisibleOnPageLoad:load时显示窗口
e.Modal:
f.Behaviors:弹出窗口都有哪些操作例如大小化、关闭等
g.Title:
h.VisibleStatusbar:隐藏状态条
例:
3
RadDateTimePicker日期控件
<telerik:RadDateTimePicker ID="RadDateBirthday" runat="server" MinDate="2009-01-09"
ShowPopupOnFocus="true">
<DateInput BorderColor="Blue" DateFormat="yyyy-MM-dd">
</DateInput>
<Calendar runat="server" ID="calendar">
</Calendar>
<DatePopupButton runat="server" Visible="true" />
</telerik:RadDateTimePicker>
a.ShowPopupOnFocus="true" 点击文本框时显示时间panel
b.DateFormat 格式化时间
========
一个Asp.net MVC 控件项目分析---Telerik.Web.Mvc
在写本文之前,本人一直抱着‘不宜’在asp.net MVC框架下搞什么控件开发的想法,因为一提到控件就会让人想起‘事件’,‘VIEWSTATE’等一些问题,而asp.net MVC下是Controller, Action, Viewpage, Filter等特性
的‘天下’。所以总感觉‘驴唇对不上马嘴’。
但直到前阵子在邮箱中收到了关于telerik关于MVC框架扩展的一些信息之后,才发现这家商业控件公司也开
始打MVC的主意了。而这个项目(开源)就是该公司在理解了asp.net mvc的基础上所做的一些尝试,当然其所实现
的所谓控件与之前我们在项目中所开发或使用的web服务器控件有很大的不同,可以说是抛弃了以往的设计方式。尽
管目前它的这种做法我心里还打着问号,但必定是一种尝试(不管你赞同还是不赞同)。下面就做一个简单的分析
,希望能给研究MVC架构的朋友提供一些的思考。
首先要声明的是该开源项目中所使用的js就是jquery,而那些显示效果也基本上就是基于jquery中的那件插
件为原型,并进行相应的属性封装,以便于在viewpage中用c#等语言进行声明绑定。下面就其中一些控件的显示截
图:
telerik_mvc_accordion
telerik_mvc_date
telerik_mvc_slider
telerik_mvc_progressbar
在该开源项目中,所有控件均基于jQueryViewComponentBase (abstract 类型),但其自身属性并不多,而
所有的控件基类属性都被jQueryViewComponentBase 的父类ViewComponentBase所定义,下面以控件中
的“Accordion(属性页控件)”为例进行说明,见下图:
telerik_mvc_baseclass
上图中左侧的就是ViewComponentBase类,其定义了多数控件属性,比如js脚本名称和路径以及相关样式以及
最终的html元素输出方法,因为其类也是抽象类,所以其中大部分方法均为定义,而未进行具体实现。我们只要关
注一下其构造方法就可以了:
/// <summary>
/// View component base class.
/// </summary>
public abstract class ViewComponentBase : IStyleableComponent, IScriptableComponent
{
private string name;
private string styleSheetFilesLocation;
private string scriptFilesLocation;
/// <summary>
/// 初始化相关Initializes a new instance of the <see cref="ViewComponentBase"/> class.
/// </summary>
/// <param name="viewContext">当前视图的上下文,将会在子类中使用</param>
/// <param name="clientSideObjectWriterFactory">传入当前所使用的Writer工厂实例.通过子类注入,
子类最终延伸到相对应的控件实例</param>
protected ViewComponentBase(ViewContext viewContext, IClientSideObjectWriterFactory
clientSideObjectWriterFactory)
{
Guard.IsNotNull(viewContext, "viewContext");
Guard.IsNotNull(clientSideObjectWriterFactory, "clientSideObjectWriterFactory");
ViewContext = viewContext;
ClientSideObjectWriterFactory = clientSideObjectWriterFactory;
StyleSheetFilesPath = WebAssetDefaultSettings.StyleSheetFilesPath;
StyleSheetFileNames = new List<string>();
ScriptFilesPath = WebAssetDefaultSettings.ScriptFilesPath;
ScriptFileNames = new List<string>();
HtmlAttributes = new RouteValueDictionary();
}
通过上述的构造方法,就可以将控件的一些通用默认属性值进行初始化了。
下面以“Accordion”的源码来分析一下,这里还是从构造方法入手:
public class Accordion : jQueryViewComponentBase, IAccordionItemContainer
{
……
/// <summary>
/// Initializes a new instance of the <see cref="Accordion"/> class.
/// </summary>
/// <param name="viewContext">The view context.</param>
/// <param name="clientSideObjectWriterFactory">The client side object writer factory.</param>
public Accordion(ViewContext viewContext, IClientSideObjectWriterFactory
clientSideObjectWriterFactory) : base(viewContext, clientSideObjectWriterFactory)
{
Items = new List<AccordionItem>();
autoHeight = true;
}
注:上面的构程方法后面加入了base(viewContext, clientSideObjectWriterFactory),以实现向基类构造
方法传参,也就是实现了上面所说的将当前控件所使用的viewContext,clientSideObjectWriterFactory传递到基
类ViewComponentBase 中去。(注:最终的clientSideObjectWriterFactory为ClientSideObjectWriterFactory实
例类型)。
当然,因为该控件的中相应属性比较简单,只是一些set,get语法,所以就不过多介绍了,相信做过控件开发
的对这些再熟悉不过了。
下面主要介绍一下其write html元素时所使用的方法,如下:
/// <summary>
/// 创建并写入初始化脚本对象和相应属性.
/// </summary>
/// <param name="writer">The writer.</param>
public override void WriteInitializationScript(TextWriter writer)
{
int selectedIndex = Items.IndexOf(GetSelectedItem());
IClientSideObjectWriter objectWriter = ClientSideObjectWriterFactory.Create(Id,
"accordion", writer);
objectWriter.Start()
.Append("active", selectedIndex, 0)
.Append("animated", AnimationName)
.Append("autoHeight", AutoHeight, true)
.Append("clearStyle", ClearStyle, false)
.Append("collapsible", CollapsibleContent, false)
.Append("event", OpenOn)
.Append("fillSpace", FillSpace, false);
if (!string.IsNullOrEmpty(Icon) || !string.IsNullOrEmpty(SelectedIcon))
{
if (!string.IsNullOrEmpty(Icon) && !string.IsNullOrEmpty(SelectedIcon))
{
objectWriter.Append("icons:{'header':'" + Icon + "','headerSelected':'" +
SelectedIcon + "'}");
}
else if (!string.IsNullOrEmpty(Icon))
{
objectWriter.Append("icons:{'header':'" + Icon + "'}");
}
else if (!string.IsNullOrEmpty(SelectedIcon))
{
objectWriter.Append("icons:{'headerSelected':'" + SelectedIcon + "'}");
}
}
objectWriter.Append("change", OnChange).Complete();
base.WriteInitializationScript(writer);
}
可以看出,objectWriter (IClientSideObjectWriter 类型实例)中被绑定了相关的控件属性,并通过其类
的WriteInitializationScript(writer)进行脚本的输出。而基本类的相应方法如下:
/// <summary>
/// Writes the initialization script.
/// </summary>
/// <param name="writer">The writer.</param>
public virtual void WriteInitializationScript(TextWriter writer)
{
}
大家看到该方法为空,但其又是如何运行起来的呢,这里先卖个关子,稍后再说。接着再看一下另一个方法
:WriteHtml()
/// <summary>
/// 输出当前的 HTML代码.
/// </summary>
protected override void WriteHtml()
{
AccordionItem selectedItem = GetSelectedItem();
TextWriter writer = ViewContext.HttpContext.Response.Output;
if (!string.IsNullOrEmpty(Theme))
{
writer.Write("<div class=\"{0}\">".FormatWith(Theme));
}
HtmlAttributes.Merge("id", Id, false);
HtmlAttributes.AppendInValue("class", " ", "ui-accordion ui-widget ui-helper-reset");
writer.Write("<div{0}>".FormatWith(HtmlAttributes.ToAttributeString()));
foreach (AccordionItem item in Items)
{
item.HtmlAttributes.AppendInValue("class", " ", "ui-accordion-header ui-helper-reset
ui-state-default ");
item.ContentHtmlAttributes.AppendInValue("class", " ", "ui-accordion-content ui-
helper-reset ui-widget-content ui-corner-bottom");
if (item == selectedItem)
{
item.ContentHtmlAttributes.AppendInValue("class", " ", "ui-accordion-content-
active");
}
else
{
item.HtmlAttributes.AppendInValue("class", " ", "ui-corner-all");
}
writer.Write("<h3{0}><a href=\"#\">{1}</a></h3>".FormatWith
(item.HtmlAttributes.ToAttributeString(), item.Text));
item.ContentHtmlAttributes.AppendInValue("style", ";", (item == selectedItem) ?
"display:block" : "display:none");
writer.Write("<div{0}>".FormatWith(item.ContentHtmlAttributes.ToAttributeString()));
item.Content();
writer.Write("</div>");
}
writer.Write("</div>");
if (!string.IsNullOrEmpty(Theme))
{
writer.Write("</div>");
}
base.WriteHtml();
}
该方法首先获取当前所选属性页标签(GetSelectedItem()方法),然后用foreach方法对属性页标签集合进
行遍历,并判断当前属性页是否就是被选中的属性页,并绑定上相应的css属性。其最终也是调用相应的基类方法进
行输出。当然这里基类方法也是为空,呵呵。
准备好了这个控件类之后,Telerik还为Accordion控件‘准备’了一些辅助组件,比如属性页组件
(AccordionItem),以及相关的组件构造器(AccordionItemBuilder,AccordionBuilder),这样我们就可以通过
这些构造器很方便的创建相应的控件和组件了,下面就以AccordionItemBuilder为例,解释一下其构造器结构:
public class AccordionBuilder : ViewComponentBuilderBase<Accordion, AccordionBuilder>,
IHideObjectMembers
{
/// <summary>
/// 初始化方法Initializes a new instance of the <see cref="AccordionBuilder"/> class.
/// </summary>
/// <param name="component">The component.</param>
public AccordionBuilder(Accordion component) : base(component)
{}
/// <summary>
/// 指定一个属性页选项
/// </summary>
/// <param name="addAction">要添加的action.</param>
/// <returns></returns>
public virtual AccordionBuilder Items(Action<AccordionItemFactory> addAction)
{
Guard.IsNotNull(addAction, "addAction");
AccordionItemFactory factory = new AccordionItemFactory(Component);
addAction(factory);
return this;
}
/// <summary>
/// 属性页动态效果显示名称(鼠标在属性页移入移出时)
/// </summary>
/// <param name="effectName">Name of the effect.</param>
/// <returns></returns>
public virtual AccordionBuilder Animate(string effectName)
{
Component.AnimationName = effectName;
return this;
}
/// <summary>
/// 是否高度自适用.
/// </summary>
/// <param name="value">if set to <c>true</c> value.</param>
/// <returns></returns>
public virtual AccordionBuilder AutoHeight(bool value)
{
Component.AutoHeight = value;
return this;
}
/// <summary>
/// 指定要触发的属性页事件名称.
/// </summary>
/// <param name="eventName">Name of the event.</param>
/// <returns></returns>
public virtual AccordionBuilder OpenOn(string eventName)
{
Component.OpenOn = eventName;
return this;
}
/// <summary>
/// 所使用的Icons名称.
/// </summary>
/// <param name="name">The name.</param>
/// <returns></returns>
public virtual AccordionBuilder Icon(string name)
{
Component.Icon = name;
return this;
}
/// <summary>
/// 被选中的属性页所使用的Icons 名称
/// </summary>
/// <param name="name">The name.</param>
/// <returns></returns>
public virtual AccordionBuilder SelectedIcon(string name)
{
Component.SelectedIcon = name;
return this;
}
/// <summary>
/// 当属性页发生变化时要传递的action 脚本.
/// </summary>
/// <param name="javaScript">The java script.</param>
/// <returns></returns>
public virtual AccordionBuilder OnChange(Action javaScript)
{
Component.OnChange = javaScript;
return this;
}
/// <summary>
/// Specify the name of the theme applies to the accordion.
/// </summary>
/// <param name="name">The name.</param>
/// <returns></returns>
public virtual AccordionBuilder Theme(string name)
{
Component.Theme = name;
return this;
}
}
对于上面的OnChange方法,可以使用下面的方法将相应的js脚本传入并执行
.OnChange(() =>
{%>
function(event, ui)
{
$('#trace').append('Change fired: ' + new Date() +
'<br/>');
}
<%}
)
这样,当属性页发生变化时,就会在页面的指定区域将变化时间显示出来了,如下图:
telerik_mvc_onchange
Telerik在jQueryViewComponentFactory中对项目中每一个控件提供了一个方法用以初始化相应的构造器,以便
于创建相应的控件,比如Accordion,形如:
/// <summary>
/// Creates a accordion for ASP.NET MVC view.
/// </summary>
/// <returns></returns>
[DebuggerStepThrough]
public virtual AccordionBuilder Accordion()
{
return new AccordionBuilder(Create(() => new Accordion(ViewContext,
clientSideObjectWriterFactory)));
}
而对于其在VIEW中的使用,则通过扩展方法来加以声明:
public static class HtmlHelperExtension
{
private static readonly IClientSideObjectWriterFactory factory = new
ClientSideObjectWriterFactory();
/// <summary>
/// Gets the jQuery view components instance.
/// </summary>
/// <param name="helper">The html helper.</param>
/// <returns>jQueryViewComponentFactory</returns>
[DebuggerStepThrough]
public static jQueryViewComponentFactory jQuery(this HtmlHelper helper)
{
return new jQueryViewComponentFactory(helper, factory);
}
}
这样在页面视图中,我们这可以使用下面的写法来构造一个Accordion控件了:
<% Html.jQuery().Accordion()
.Name("myAccordion")
.Animate("bounceslide")
.Items(parent =>
……
上面只是介绍了前台和底层代码如果显示的问题,但还没有解释之前所说的WriteInitializationScript
(TextWriter writer)方法以及WriteHtml()
方法如何被调用的问题,正如之前所看到的,因为Accordion的基类ViewComponentBase中未实现具体的代码,所以
这里我们要将注意力转移到 jQueryViewComponentFactory中,请看如下代码:
private TViewComponent Create<TViewComponent>(Func<TViewComponent> factory) where TViewComponent :
ViewComponentBase
{
TViewComponent component = factory();
if (component is jQueryViewComponentBase)
{
component.AssetKey = DefaultAssetKey;
}
htmlHelper.Telerik().StyleSheetRegistrar().ToRegistrar().Register(component);
htmlHelper.Telerik().ScriptRegistrar().ToRegistrar().Register(component);
return component;
}
上面的方法其实就是之前在该类方法Accordion()中所调用并执行的:
return new AccordionBuilder(Create(() => new Accordion(ViewContext,
clientSideObjectWriterFactory)));
通过该方法,就可以将该控件及其相关组件信息注册到相应的视图中。因为我们比较关注WriteHtml()方法,
所以这里就直接分析一下这一行代码:
ScriptRegistrar().ToRegistrar().Register(component);
ScriptRegistrar类中的Register方法承担着将当前要创建的组件添加到当前的脚本组件列表中的任务
(scriptableComponents为list列表)
/// <summary>
/// Registers the scriptable component.
/// </summary>
/// <param name="component">The component.</param>
public virtual void Register(IScriptableComponent component)
{
Guard.IsNotNull(component, "component");
if (!scriptableComponents.Contains(component))
{
scriptableComponents.Add(component);
}
}
当组件被成功添加到该list列表中后,系统就会调用Render()方法将其显示出来(注:该方法与以前web控件
开发中的显示方法同名,所以比较好理解),如下:
/// <summary>
/// Writes the scripts in the response.
/// </summary>
public void Render()
{
if (hasRendered)
{
throw new InvalidOperationException
(Resources.TextResource.YouCannotCallRenderMoreThanOnce);
}
if (ViewContext.HttpContext.Request.Browser.EcmaScriptVersion.Major >= 1)
{
Write(ViewContext.HttpContext.Response.Output);
}
hasRendered = true;
}
注意上面的这一行代码:
Write(ViewContext.HttpContext.Response.Output);
其所实现的功能如下:
/// <summary>
/// 写出所有脚本资源和脚本 statements.
/// </summary>
/// <param name="writer">The writer.</param>
protected virtual void Write(TextWriter writer)
{
WriteScriptSources(writer);
WriteScriptStatements(writer);
}
而就是WriteScriptStatements这行代码开始执行之前所说的那个WriteInitializationScript(TextWriter
writer)。而WriteHtml()方法的执行入口要更加复杂一些,因为Telerik提供了ViewComponentBuilderBase这个类来
进行视图组件的构造,而该类中的Render方法就是对相应组件的Render方法(组件中已定义)进行调用,如下:
/// <summary>
/// Renders the component.
/// </summary>
public virtual void Render()
{
Component.Render();
}
而之前的“Accordion”控件是继承自ViewComponentBase类,所以相应组件的Render方法就在该类中进行了
声明定义,如下:
/// <summary>
/// Renders the component.
/// </summary>
public void Render()
{
EnsureRequired();
WriteHtml();
}
大家看到了第二行代码了吧,这就是我们之前看到的那个方法,也就是Accordion组件中WriteHtml()重写方
法的调用入口。
绕了这么一大圈,才把这个流程理清,是不是有些晕了。的确,刚开始接触时我也有点晕,但晕呀晕呀就‘
晕过去了’,现在再回头看起来感常见其整体的架构思路还是很清晰的。可以说有了这瓶酒垫底,再分析该项目中
的其它控件就‘如鱼得水’了。
最后不妨总结一下:
该项目中对asp.net mvc控件下的开发做了一次尝试,但如果之前做过控件特别是web服务器端控件开发的朋
友,可以看出项目中有非常重的web控件开发味道,基本连方法名称都有一定的重叠。
另外就是其自身还是引用了组件对象模型的概念,就拿属性页控件来说,就将其分为Accordion和
AccordionItem两种类型,其中可以将Accordion看成是AccordionItem的集合封装(包括遍历操作),而这里
AccordionItem就成了Accordion的一个组件,而Accordion又是当前view中的一个组件。而组件开发一直是.net平台
上所倡导的。其优势在于可复用,维护方便,简化复杂问题等。
好了,今天的内容就先到这里了。
http://www.cnblogs.com/daizhj/archive/2009/09/09/1562966.html
========
Telerik RadGrid - DataSet (增删查改)
Telerik RadGrid 数据展现、修改、删除、增加, 数据源使用后台DataSet绑定.RadGrid支持弹出编辑形式。 条件是需要设置EditMode属性弹出。 EditMode="PopUp"
<telerik:RadGrid ID="RadGrid1" runat="server" GridLines="None"
AllowPaging="True" PageSize="10" AllowSorting="True" AutoGenerateColumns="false"
ShowStatusBar="true" AllowAutomaticDeletes="True" AllowAutomaticInserts="True"
AllowAutomaticUpdates="True" HorizontalAlign="NotSet"
onupdatecommand="RadGrid1_UpdateCommand"
onneeddatasource="RadGrid1_NeedDataSource" ondeletecommand="RadGrid1_DeleteCommand"
oninsertcommand="RadGrid1_InsertCommand">
<MasterTableView CommandItemDisplay="TopAndBottom" DataKeyNames="MenuID" EditMode="PopUp">
<CommandItemSettings ExportToPdfText="Export to Pdf" AddNewRecordText="添加新项"
RefreshText="更新"></CommandItemSettings>
<Columns>
<telerik:GridEditCommandColumn EditText="修改">
</telerik:GridEditCommandColumn>
<telerik:GridBoundColumn UniqueName="MenuID" HeaderText="菜单序号"
DataField="MenuID">
<HeaderStyle Width="60px"></HeaderStyle>
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="SortNo" HeaderText="排序序号"
DataField="SortNo">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="ParentID" HeaderText="父节点"
DataField="ParentID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Name" HeaderText="名称" DataField="Name">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="IconUrl" HeaderText="图标路径"
DataField="IconUrl">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn UniqueName="Url" HeaderText="链接路径" DataField="Url">
</telerik:GridBoundColumn>
<telerik:GridButtonColumn CommandName="Delete" Text="删除" ConfirmText="确定删除吗?"
UniqueName="column">
</telerik:GridButtonColumn>
</Columns>
<EditFormSettings InsertCaption="添加新数据" CaptionFormatString="修改 菜单序号: {0}"
CaptionDataField="MenuID" EditFormType="Template"
PopUpSettings-Modal="true">
<EditColumn UniqueName="EditCommandColumn1" EditText="修改"></EditColumn>
<FormTemplate>
<table id="Table1" cellspacing="1" cellpadding="1" width="250" border="0">
<tr>
<td>
排序序号:
</td>
<td>
<asp:TextBox ID="txtSortNo" Text='<%# Bind( "SortNo") %>'
runat="server">
</asp:TextBox>
</td>
</tr>
<tr>
<td>
父节点:
</td>
<td>
<asp:TextBox ID="txtParentID" Text='<%# Bind( "ParentID") %>'
runat="server">
</asp:TextBox>
</td>
</tr>
<tr>
<td>
名称:
</td>
<td>
<asp:TextBox ID="txtName" Text='<%# Bind( "Name") %>' runat="server">
</asp:TextBox>
</td>
</tr>
<tr>
<td colspan="2">
<hr />
</td>
</tr>
<tr>
<td>
是否启用:
</td>
<td>
<asp:CheckBox ID="ckEnable" runat="server" Checked='<%# (Container is
GridEditFormInsertItem) ? false : Eval("IsEnable") %>'/>
</td>
</tr>
<tr>
<td>
图标路径:
</td>
<td>
<asp:TextBox ID="txtIconUrl" runat="server" Text='<%# Bind( "IconUrl"
) %>'>
</asp:TextBox>
</td>
</tr>
<tr>
<td>
链接路径:
</td>
<td>
<asp:TextBox ID="txtUrl" runat="server" Text='<%# Bind( "Url") %>'>
</asp:TextBox>
</td>
</tr>
</table>
<table style="width: 100%">
<tr>
<td align="right" colspan="2">
<asp:Button ID="Button1" Text='<%# (Container is
GridEditFormInsertItem) ? "插入" : "更新" %>'
runat="server" CommandName='<%# (Container is
GridEditFormInsertItem) ? "PerformInsert" : "Update" %>'>
</asp:Button>
<asp:Button ID="Button2" Text="取消" runat="server"
CausesValidation="False" CommandName="Cancel">
</asp:Button>
</td>
</tr>
</table>
</FormTemplate>
</EditFormSettings>
<PagerStyle FirstPageToolTip="首页" LastPageToolTip="尾页" NextPagesToolTip="下一页"
NextPageToolTip="下一页"
PageSizeLabelText="页数:" PrevPagesToolTip="上一页" PrevPageToolTip="上一页" />
</MasterTableView>
</telerik:RadGrid>
ShowStatusBar="true" //显示工具栏
EditFormType="Template" //所有类型的编辑形式弹出可以显示在编辑类型AutoGenerated、WebUserControl和
Template
在弹出EditForm设置GridEditFormSettings控制通过的PopUpSettings属性对象。 它暴露3属性:
高度 -定义的百分比或弹出高度的像素
宽度-定义宽度的百分比或弹出像素
滚动条-定义是否应显示滚动条并在编辑表格。此设置优先级较高,因此,如果高度设置,但不显示垂直滚动条的内
容需要更多的空间,在弹出会被重新调整,以适应整个内容。默认值为 None。
设置下DataSet , 方便后面调用.
public DataSet MenuData
{
get
{
object obj = this.Session["MenuData"];
if (obj != null)
{
return (DataSet)obj;
}
DataSet menuData = new DataSet();
String ConnString = ConfigurationManager.ConnectionStrings
["ConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(ConnString);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand("SELECT * FROM Menu", conn);
adapter.Fill(menuData, "Menu");
this.Session["MenuData"] = menuData;
return menuData;
}
}
绑定RadGird,在NeedDataSource事件里绑定~
protected void RadGrid1_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
{
this.RadGrid1.DataSource = MenuData;
this.MenuData.Tables["Menu"].PrimaryKey = new DataColumn[] { this.MenuData.Tables
["Menu"].Columns["MenuID"] };//设置主键
}
UpdateCommand事件里实现修改.
protected void RadGrid1_UpdateCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
DataRow[] changedRows = MenuData.Tables["Menu"].Select("MenuID = " +
editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]["MenuID"]);
if (changedRows.Length != 1)
{
e.Canceled = true;
return;
}
Hashtable newValues = new Hashtable();
newValues["SortNo"] = (editedItem.FindControl("txtSortNo") as TextBox).Text;
newValues["ParentID"] = (editedItem.FindControl("txtParentID") as TextBox).Text;
newValues["Name"] = (editedItem.FindControl("txtName") as TextBox).Text;
newValues["IsEnable"] = (editedItem.FindControl("ckEnable") as CheckBox).Checked;
newValues["IconUrl"] = (editedItem.FindControl("txtIconUrl") as TextBox).Text;
newValues["Url"] = (editedItem.FindControl("txtUrl") as TextBox).Text;
newValues["MenuID"] = editedItem.OwnerTableView.DataKeyValues[editedItem.ItemIndex]
["MenuID"];
changedRows[0].BeginEdit();
try
{
//遍历,把数据存到DataRow
foreach (DictionaryEntry entry in newValues)
{
changedRows[0][(string)entry.Key] = entry.Value;
}
changedRows[0].EndEdit();
this.MenuData.AcceptChanges(); //更新数据源
MSSQL.SqlServerHelper.UpdateMenu(); //更新数据库方法
}
catch (Exception ex)
{
changedRows[0].CancelEdit();
RadGrid1.Controls.Add(new LiteralControl("Unable to update Employees. Reason: " +
ex.Message));
e.Canceled = true;
}
RadGrid1.MasterTableView.Items[e.Item.ItemIndex].Edit = false;//关闭当前修改窗口
}
RadGrid1_InsertCommand 增加~
protected void RadGrid1_InsertCommand(object source, GridCommandEventArgs e)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
DataRow newRow = MenuData.Tables["Menu"].NewRow();
Hashtable newValues = new Hashtable();
newValues["SortNo"] = (editedItem.FindControl("txtSortNo") as TextBox).Text;
newValues["ParentID"] = (editedItem.FindControl("txtParentID") as TextBox).Text;
newValues["Name"] = (editedItem.FindControl("txtName") as TextBox).Text;
newValues["IsEnable"] = (editedItem.FindControl("ckEnable") as CheckBox).Checked;
newValues["IconUrl"] = (editedItem.FindControl("txtIconUrl") as TextBox).Text;
newValues["Url"] = (editedItem.FindControl("txtUrl") as TextBox).Text;
//获取表Menu最后一个的ID + 1
newValues["MenuID"] = (int)this.MenuData.Tables["Menu"].Rows[this.MenuData.Tables
["Menu"].Rows.Count - 1]["MenuID"] + 1;
try
{
foreach (DictionaryEntry entry in newValues)
newRow[(string)entry.Key] = entry.Value;
this.MenuData.Tables["Menu"].Rows.Add(newRow);
this.MenuData.Tables["Menu"].AcceptChanges();
MSSQL.SqlServerHelper.Insert();
}
catch (Exception ex)
{
e.Canceled = true;
}
}
RadGrid1_DeleteCommand 删除~
string ID = e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["MenuID"].ToString();
DataSet ds = (DataSet)Session["MenuData"];
if (ds.Tables["Menu"].Rows.Find(ID) != null)
{
ds.Tables["Menu"].Rows.Find(ID).Delete();
ds.Tables["Menu"].AcceptChanges();
MSSQL.SqlServerHelper.DeleteMenu(ID);
Session["DataSource"] = ds.Tables["Menu"];
}
前台页面一些效果.
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
<AjaxSettings>
<telerik:AjaxSetting AjaxControlID="RadGrid1">
<UpdatedControls>
<telerik:AjaxUpdatedControl ControlID="RadGrid1" />
</UpdatedControls>
</telerik:AjaxSetting>
</AjaxSettings>
</telerik:RadAjaxManager>
双击行, 编辑状态:
在RadGrid里加入
<ClientSettings>
<ClientEvents OnRowDblClick="RowDblClick" />
</ClientSettings>
JS加入:
function RowDblClick(sender, eventArgs) {
sender.get_masterTableView().editItem(eventArgs.get_itemIndexHierarchical());
}
细节:
因为是英文的,所以可以找到****Text去改文本,那样提示或文本都是中文的了 - -,
<%# (Container is GridEditFormInsertItem) ? "插入" : "更新" %> . 因为插入更新用的是同一个窗口~ 所以用
这句判断是插入还是更新~
========
Telerik RadGrid - SessionDataSource
Telerik_Web_UI第一天-Telerik RadGrid 数据展现, 使用官方的SessionDataSource~
1.导入<%@ Register TagPrefix="sds" Namespace="Telerik.Web.SessionDS" %>
2.配置SessionDataSource选项
1 <sds:SessionDataSource ID="SessionDataSource1" ConnectionString="<%$
ConnectionStrings:NorthwindConnectionString %>"
2 ProviderName="System.Data.SqlClient"
3 SelectCommand="SELECT * FROM [Products]" runat="server" PrimaryKeyFields="ProductID">
4 </sds:SessionDataSource>
3.RadGrid 设置 DataSourceID="SessionDataSource1"
这时你会发现,还需要(SessionDataSource.cs),这个文件在安装目录\Live Demos\App_Code\下面.
========
Telerik RadUpload 文件类型验证
你可以使用RadUpload与ASP.NET的自定义验证器。 CustomValidator验证同时支持客户端和服务器端验证。验证客户端的好处是可以防止的CustomValidator验证时提交的文件有选择的客户端验证函数认为无效的页面。验证
功能可以使用validateExtensions()客户端的方法来验证客户端上的文件扩展名。选定的文件必须转移到服务器
才能的尺寸或MIME类型的验证。
验证服务器端的优点是您可以访问文件,如大小或MIME类型,甚至检查文件内容的信息。自定义验证器的
ServerValidate事件发生后,RadUpload ValidatingFile事件,并有完整的验证。
当使用一个CustomValidator验证,验证器的ControlToValidate属性RadUpload不得设置!
先上图:
Upload控件需要几个js的支持, Telerik 的 dll 自带了需要的js.
<telerik:RadScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
<asp:ScriptReference Assembly="Telerik.Web.UI"
Name="Telerik.Web.UI.Common.jQueryInclude.js" />
</Scripts>
</telerik:RadScriptManager>
<div class="MainWrap">
<div class="TopWrap">
<div class="Holder">
<telerik:RadAsyncUpload runat="server" ID="RadAsyncUpload1"
AllowedFileExtensions="jpg,jpeg,png,gif"
MaxFileSize="1048576" OnClientValidationFailed="validationFailed"
OnValidatingFile="RadAsyncUpload1_ValidatingFile"
OnFileUploaded="RadAsyncUpload1_FileUploaded" InputSize="42" Skin="Windows7" >
</telerik:RadAsyncUpload>
<asp:Button runat="server" ID="BtnSubmit" Text="上传" />
<p>
选择要上传的图片 (jpg, jpeg, png, gif)
</p>
<p>
图片最大不能超过 1M 大小.
</p>
<div class="ErrorHolder">
</div>
</div>
<div class="Holder Right">
<asp:Panel runat="server" ID="ResultsPanel" Visible="false">
<asp:Panel ID="ValidFiles" Visible="false" runat="server">
<p>
<strong>图像保存到目标文件夹: /File/</strong>
</p>
</asp:Panel>
<asp:Panel ID="InvalidFiles" Visible="false" runat="server">
<p>
<strong>下面的图片不被保存,由于超过最大大小:</strong>
</p>
</asp:Panel>
</asp:Panel>
</div>
<div class="BottomWrap">
</div>
</div>
</div>
const int MaxTotalBytes = 1048576; // 1 MB
int totalBytes;
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
ResultsPanel.Visible = true;
}
}
public void RadAsyncUpload1_FileUploaded(object sender, FileUploadedEventArgs e)
{
Label fileName = new Label();
fileName.Text = e.File.FileName;
e.File.SaveAs(Server.MapPath("../file/"+e.File.FileName),true);//保存文件
if (e.IsValid)
{
ValidFiles.Visible = true;
ValidFiles.Controls.Add(fileName);
}
else
{
InvalidFiles.Visible = true;
InvalidFiles.Controls.Add(fileName);
}
}
public void RadAsyncUpload1_ValidatingFile(object sender,
Telerik.Web.UI.Upload.ValidateFileEventArgs e)
{
if (totalBytes < MaxTotalBytes)
{
// 没有达到限制的总字节数,运行文件上传
e.IsValid = true;
totalBytes += e.UploadedFile.ContentLength;
}
else
{
// 达到限制的总字节数,放弃文件上传
e.IsValid = false;
}
}
========
相关文章推荐
- 如何在 Linux/Windows/MacOS 上使用 .NET 进行开发
- 如何在 Linux 中安装微软的 .NET Core SDK
- C#.NET获取拨号连接的宽带连接方法
- C#.Net ArrayList的使用方法
- PowerShell中使用.NET将程序集加入全局程序集缓存
- .net(c#)中的new关键字详细介绍
- 由vbs sort引发.NET Framework之间的关系说明
- C#难点逐个击破(6):C#数据类型与.net framework数据类型
- .NET中的async和await关键字使用及Task异步调用实例
- 基于.NET平台常用的框架和开源程序整理
- .Net中的json操作类用法分析
- .net实现序列化与反序列化实例解析
- .NET中的Timer类型用法详解
- Microsoft .Net Remoting系列教程之二:Marshal、Disconnect与生命周期以及跟踪服务
- 关于.net(C#)中的跨进程访问的问题
- .NET实现父窗体关闭而不影响子窗体的方法
- 基于.Net中的数字与日期格式化规则助记词的使用详解
- .NET微信公众号开发之公众号消息处理
- .Net下的签名与混淆图文分析
- .NET 扩展实现代码