asp.net 2.0实战(2) 在GridView或DetailsView中加入日期选择和图片上传修改的自定义控件_jaye.net

一.日期选择控件

GridView中的日期字段输入,实在是一个麻烦的事情,因为对一般的用户来讲,不知道输入日期的那种格式,如果日期的输入不是文本输入而是从日历控件中选择,那就要好多了.

这就要建一个自定义控件.

1.建立一个简单的自定义日期选择控件

在可视视窗下,放入一个TextBox,一个button,一个日历控件

pickdate.ascx的参考源代码:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="pickdate.ascx.cs" Inherits="pickdate" %>
&nbsp;<asp:TextBox ID="TBDate" runat="server" Width="83px"></asp:TextBox><asp:Button
ID="Button1" runat="server" OnClick="Button1_Click" Text="▼" ToolTip="日期选择器"
Width="29px" />
<asp:Calendar ID="Calendar1" runat="server" Height="149px" OnSelectionChanged="Calendar1_SelectionChanged"
Width="157px" BackColor="#FFFFCC" BorderColor="#FFCC66" BorderWidth="1px" DayNameFormat="Shortest" Font-Names="Verdana" Font-Size="8pt" ForeColor="#663399" ShowGridLines="True" Visible="False" >
<SelectedDayStyle BackColor="#CCCCFF" Font-Bold="True" />
<SelectorStyle BackColor="#FFCC66" />
<OtherMonthDayStyle ForeColor="#CC9966" />
<TodayDayStyle BackColor="#FFCC66" ForeColor="White" />
<NextPrevStyle Font-Size="9pt" ForeColor="#FFFFCC" />
<DayHeaderStyle BackColor="#FFCC66" Font-Bold="True" Height="1px" />
<TitleStyle BackColor="#990000" Font-Bold="True" Font-Size="9pt" ForeColor="#FFFFCC" />
</asp:Calendar>

在codeFile里设置必要的属性和事件处理

参考代码如下:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class pickdate : System.Web.UI.UserControl
{
private DateTime m_thisdate;//多余的

public DateTime thisdate
{
get {
if (TBDate.Text != string.Empty)    
{
return DateTime.Parse(TBDate.Text);
}
else
{
return DateTime.Now.Date;
}

}
set {

TBDate.Text = value.Date.ToShortDateString();   //不需要判断value,因为一定为日期型
Calendar1.SelectedDate = value;
Calendar1.VisibleDate = value;
}
}

protected void Page_Load(object sender, EventArgs e)
{

}
protected void Calendar1_SelectionChanged(object sender, EventArgs e)

{
TBDate.Text = Calendar1.SelectedDate.ToShortDateString(); ;
}
protected void Button1_Click(object sender, EventArgs e)  //操纵日历的可视状态
{
Calendar1.Visible = !Calendar1.Visible;
if (Calendar1.Visible)
{
Button1.Text = "▲";
}
else
{
Button1.Text = "▼";
}
}
}

2把要用这个控件的列转为模板,然后在Edit模板中放入这个控件,在源代码视图进行绑定(可视状态无法绑定,因为绑定的属性选项中不出现thisdate属性)

<EditItemTemplate>

<uc1:pickdate ID="Pickdate1" runat="server" thisdate='<%# Bind("begindate") %>' />

</EditItemTemplate>

ok.这样就可以在GridView中用选择日期的方式输入日期了,缺点在于:要求对应的数据库的字段必须为Date,而且有值,否则会出现绑定错误("Specified cast is not valid.") ,试图对value是否是Null判断( if (value == null)) ,但是没有用。因为设置断点发现错误发生在属性设置之前(set),出错在 <uc1:pickdate ID="Pickdate1" runat="server" thisdate='<%# Bind("begindate") %>' />

希望各位告知处理的方法.

二.图像上传控件

 

1.在GridView或DetailsView中加入Template

 <ItemTemplate>
<uc1:imageupload ID="Imageupload1" runat="server" thisphoto='<%# Eval("UserName") %>' Alt='<%# Eval("des") %>' />
</ItemTemplate>

同样,绑定需要在源代码中改,可视化绑定无法找到thisphoto和Alt两个属性

2.对sqlDataSource的处理

大家看到当鼠标移到图片上后,自动会出现图片的描述其实是ALT属性,此属性当然是从数据库读取,那么如何让DataSource产生这个描述字段呢?

一种方法是用ObjectDataSource(请参阅我的第一篇

asp.net 2.0 实战(1)_自定义动态新闻列表的制作_jaye.net

 )

但是其实这里也可以不需要用ObjectDataSource(用了更好,能更好地控制格式),用SqlDataSource也可以实现。如下所示:

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:bobbyConnectionString %>"
SelectCommand="SELECT [UserName], 'des'='用户名:'+[UserName]+CHAR(13)+'地址:'+[Addr]+CHAR(13)+'电话:'+[phone]+CHAR(13)+'QQ:'+[QQ]+CHAR(13)+'身份证:'+[IC]+CHAR(13) FROM [User_Detail] WHERE ([UserName] = @UserName)">
<SelectParameters>
<asp:ControlParameter ControlID="TextBox2" Name="UserName" PropertyName="Text" Type="String" />
</SelectParameters>
</asp:SqlDataSource>

在SelectCommand的SELECT语句中营造一个'des'字段,此字段是其它真正存在的描述字段的一个组合

 3.设计自定义控件

imageupload.ascx部分参考为:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="imageupload.ascx.cs" Inherits="imageupload" %>
<asp:Panel ID="Panel1" runat="server" Height="198px" Width="204px">
&nbsp; &nbsp;
<asp:Image ID="Imageud" runat="server" Height="184px" Width="180px" />
<asp:FileUpload ID="FileUploadimage" runat="server" />
<asp:Button ID="Buttonupload" runat="server" OnClick="Buttonupload_Click" Text="上传" />
<asp:Label ID="Labelimage" runat="server" ForeColor="#FFC0C0"></asp:Label></asp:Panel>

imageupload.ascx.cs部分参考为:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class imageupload : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{

}
private string m_thisphoto;//多余的变量
public string thisphoto   //图片的地址属性
{
get {
return Imageud.ImageUrl;
}
set {
Imageud.ImageUrl = "~/login/userphotoHandler.ashx?id=" + value+"&size=100";//用ashx来操纵,ashx如何做等下讲,简单讲此处就是通过ashx来取得图片
}
}
private string m_Alt;//多余的变量
public string Alt      //图片的alt属性
{
get
{
return Imageud.AlternateText;
}
set
{
Imageud.AlternateText = value;
}
}
protected void Buttonupload_Click(object sender, EventArgs e)  //上传图片的简单代码
{
if (FileUploadimage.HasFile && (FileUploadimage.FileName.ToLower().EndsWith("jpg") || FileUploadimage.FileName.ToLower().EndsWith("jpeg")))
try
{
FileUploadimage.SaveAs(MapPath("~/Photo/") + Membership.GetUser().UserName + ".jpg");
Labelimage.Text = "图片修改成功";

}
catch (Exception ex)
{
Labelimage.Text = "出错";
}
else
{
Labelimage.Text = "选择本地图片,目前只接受jpg格式";
}
}
}
 

4.用ashx(userphotoHandler.ashx)中间层,用这种方法可以不把图片放入数据库,也可以做到很好的防止图片被批量下载

其实在asp.net 1.1时代就有ashx.但是我一直不知道,那时用aspx来实现现在的功能,个人感觉从实现角度讲,没有什么差别,性能方面不清楚(应该是ashx强,至少ashx不需要处理界面).

ashx用来从现有的数据库中提取image数据,或对server端的图片进行处理后输出为图片.

(1)ashx用来从现有的数据库中提取image数据:我尝试从Northwind(sql server2000)读取图片,但就是不成功,详情见我的这篇blog:

[求助] 用ashx从northwind读取图片不成功的,哪里错了

(2)对server端的图片进行处理后输出为图片,下面为参考代码:

 public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/jpeg";
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.BufferOutput = false;

string strFileName;
int BytesRead,intFileLength;
byte[] ByteValues;
System.Drawing.Image imgFullSize, imgLastSize;
MemoryStream stmimage;
strFileName = context.Server.MapPath("~/Photo/" + context.Request.QueryString["id"] + ".jpg");//传值过来图片的url属性,此处因为我是一个username只有一个对应的图片,所以这样处理,一般情况需要一个专门的imageUrl.
imgFullSize = System.Drawing.Image.FromFile(strFileName);
int intsize;
intsize = int.Parse(context.Request.Params["size"]);//传过来图片的宽度,
imgLastSize = imgFullSize.GetThumbnailImage(intsize, imgFullSize.Width * imgFullSize.Height / intsize, null, IntPtr.Zero);


stmimage = new MemoryStream();
imgLastSize.Save(stmimage, System.Drawing.Imaging.ImageFormat.Jpeg);
intFileLength = Convert.ToInt32(stmimage.Length);
ByteValues = new byte[intFileLength];
stmimage.Position = 0;
BytesRead = stmimage.Read(ByteValues, 0, intFileLength);
if (BytesRead > 0)
{
context.Response.BinaryWrite(ByteValues);
}
stmimage.Close();
//context.Response.End();

}

 

ok了,请大家指正.

posted on 2006-04-29 09:52  自由.Net  阅读(1502)  评论(1编辑  收藏  举报