博客 (22)

微软今天发布了 Net Framework 3.5 的 Chart 控件,弥补了 .Net 平台下缺乏一个十分强力的图表控件。

该图表控件支持多种图表,如饼图,柱状图,曲线图,散点图,雷达图,面积图,股票图等,同时支持 Winform 和 Asp.net。

目前该控件只能用在 .Net Framework 3.5 上,没有查找到 For .Net Framework 2.0 的信息。

补:原来该款控件来自 dundas.com,有 .Net Framework 2.0 版本,需要付费,该公司被微软收购后主推 3.5 版本,并免费。

下载信息
  1. 控件:Microsoft .NET Framework 3.5 的 Microsoft 图表控件 (Microsoft ChartControls for Microsoft .NET Framework 3.5)

    包含英文版,中文版。上面提供的链接是中文版的,可以更改为英文版。

  2. 语言包:Microsoft Chart Controls for Microsoft .NET Framework 3.5 LanguagePack

    Microsoft .NET Framework 3.5 的Microsoft 图表控件 的语言包,包含23中语言。

  3. WinForm 和 Asp.net 的例子(SamplesEnvironment for Microsoft Chart Controls)

    这个只有英文的,没找到英文的。

演示

2D的图:

3D的图:

参考资源

1. Microsoft Chart control for .NET Framework Released!

2.图片来自 http://code.msdn.microsoft.com/mschart 中的 Winform 演示。

7,684

可以创建实现模板的用户控件,这是 ASP.NET 的一项功能,它允许将控件数据与其表示形式相分离。模板化控件不提供用户界面。编写它则是为了实现一个命名容器以及包含属性和方法可由宿主页访问的类。

用户控件的用户界面由页面开发人员在设计时提供。开发人员创建由用户控件定义的类型模板,然后可以向模板添加控件和标记。

创建模板用户控件

  1. 在 .ascx 文件中,添加要在其中显示模板的 ASP.NET PlaceHolder 控件。

  2. 在用户控件的代码中,实现 ITemplate 类型的属性。

  3. 将实现 INamingContainer 接口的服务器控件类定义为要在其中创建模板实例的容器。此容器叫做模板的命名容器。

    说明:

    此控件实质上成了用户控件的嵌套类,但这不是必需的。

  4. TemplateContainerAttribute 应用于实现 ITemplate 的属性 (property),并将模板命名容器的类型作为参数传递给属性 (attribute) 的构造函数。

  5. 在控件的 Init 方法中,将以下步骤重复一次或多次:

    • 创建命名容器类的一个实例。

    • 在命名容器中创建该模板的一个实例。

    • 将命名容器实例添加到 PlaceHolder 服务器控件的 Controls 属性。

      说明:

      从使用用户控件的页面的角度来看,模板化用户控件的语法与自定义模板化控件的语法相同。

下面的示例演示一个模板化用户控件和一个包含该控件的页面。该用户控件创建一个可在宿主页上声明为 <MessageTemplate> 的模板。该模板控件还公开两个可由宿主页在模板内访问的属性:IndexMessage

第一个示例显示模板化用户控件。第二个示例显示包含该用户控件的页面。

Visual Basic
<%@ Control language="VB" ClassName="TemplatedUC" %>
<%@ Import Namespace="System.ComponentModel" %>
<script runat="server" >
 Private m_messageTemplate As ITemplate = Nothing
 <TemplateContainer(GetType(MessageContainer))> _
 <PersistenceMode(PersistenceMode.InnerProperty)> Public Property _
 MessageTemplate() As ITemplate
 Get
 Return m_messageTemplate
 End Get
 Set(ByVal value As ITemplate)
 m_messageTemplate = Value
 End Set
 End Property
 
 Sub Page_Init()
 If Not (MessageTemplate Is Nothing) Then
 Dim i As Integer
 Dim fruits() As String = _
 {"apple", "orange", "banana", "pineapple"}
 For i = 0 To 3
 Dim container As New MessageContainer(i, fruits(i))
 MessageTemplate.InstantiateIn(container)
 PlaceHolder1.Controls.Add(container)
 Next i
 End If
 End Sub
 Public Class MessageContainer
 Inherits Control
 Implements INamingContainer
 Private m_index As Integer
 Private m_message As String
 Friend Sub New(ByVal i As Integer, ByVal msg As String)
 Me.Index = i
 Me.Message = msg
 End Sub
 
 Public Property Index() As Integer
 Get
 Return m_index
 End Get
 Set(ByVal value As Integer)
 m_index = value
 End Set
 End Property
 Public Property Message() As String
 Get
 Return m_message
 End Get
 Set(ByVal value As String)
 m_message = value
 End Set
 End Property
 End Class
</script>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
<%@ Control language="C#" ClassName="TemplatedUC" %>
<%@ Import Namespace="System.ComponentModel" %>
<script runat="server">
private ITemplate messageTemplate = null;
[ TemplateContainer(typeof(MessageContainer)) ]
[ PersistenceMode(PersistenceMode.InnerProperty) ]
public ITemplate MessageTemplate {
 get 
 { 
 return messageTemplate; 
 }
 set 
 { 
 messageTemplate = value; 
 }
}
void Page_Init() {
 if (messageTemplate != null) {
 String[] fruits = {"apple", "orange", "banana", "pineapple" };
 for (int i=0; i<4; i++) 
 {
 MessageContainer container = new MessageContainer(i, fruits[i]);
 messageTemplate.InstantiateIn(container);
 PlaceHolder1.Controls.Add(container);
 }
 }
}
public class MessageContainer: Control, INamingContainer {
 private int m_index;
 private String m_message;
 internal MessageContainer(int index, String message)
 { 
 m_index = index;
 m_message = message;
 }
 public int Index {
 get 
 { 
 return m_index; 
 } 
 }
 public String Message 
 { 
 get 
 { 
 return m_message; 
 } 
 }
}
</script>
<asp:Placeholder runat="server" ID="PlaceHolder1" />
Visual Basic
<%@ Page Language="VB" %>
<%@ Register TagPrefix="uc" tagname="TemplateTest" 
 Src="TemplatedUC.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html >
<script runat="server">
 Sub Page_Load()
 DataBind()
 End Sub
</script>
<head>
<title>Templated User Control Test</title>
</head>
<body>
<h1>Testing Templated User Control</h1>
<form id="Form1" runat="server">
<uc:TemplateTest runat="server">
 <MessageTemplate>
 Index: <asp:Label runat="server" ID="Label1" 
 Text='<%# Container.Index %>' />
 <br />
 Message: <asp:Label runat="server" ID="Label2" 
 Text='<%# Container.Message %>' />
 <hr />
 </MessageTemplate>
</uc:TemplateTest>
</form>
</body>
</html>
<%@ Page Language="C#" %>
<%@ Register TagPrefix="uc" tagname="TemplateTest" 
 Src="TemplatedUC.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html >
<script runat="server">
 protected void Page_Load()
 {
 DataBind();
 }
 
</script>
<head>
<title>Templated User Control Test</title>
</head>
<body>
<h1>Testing Templated User Control</h1>
<form id="Form1" runat="server">
<uc:TemplateTest runat="server">
 <MessageTemplate>
 Index: <asp:Label runat="server" ID="Label1" 
 Text='<%# Container.Index %>' />
 <br />
 Message: <asp:Label runat="server" ID="Label2" 
 Text='<%# Container.Message %>' />
 <hr />
 </MessageTemplate>
</uc:TemplateTest>
</form>
</body>
</html>
4,300

使用AjaxControlTookit时,如果控件的右侧小箭头不出现,则可检查:
1,是否添加引用
2,工具箱中的相关选项卡对应的DLL是否跟引用中的DLL一致(可删除并重建相关选项卡)
一般情况下就可以正常使用AjaxControlTookit了。

xoyozo 16 年前
4,505

CalendarExtender 日历控件中文本地化支持

CalendarExtender 日历默认是英文,如需要中文本地化支持,则可在 <asp:ScriptManager/> 中增加以下两个属性


EnableScriptGlobalization = "true"
EnableScriptLocalization = "true"
5,500

有时候点了Button虽然能验证不能通过,但没弹出提示框,用户体验不好.
解决方法,设置验证控件的SetFocusOnError="True"就可以了.

xoyozo 17 年前
4,337

在母板页"CS"加入:

public HyperLink MasterPageHyperLink3
{

get
{
return HyperLink3;
}

set
{
HyperLink3
= value;
}
}

在子页"源"加入:

<%@ MasterType VirtualPath="~/xoyozo/xoyozo.master" %>

即可在子页重写它:

Master.MasterPageHyperLink3.NavigateUrl = "ddddddd.html";

但最好放在Page_LoadComplete:

protected void Page_LoadComplete(object sender, EventArgs e)
{
}
xoyozo 17 年前
3,298
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="calender.aspx.cs" Inherits="___TEST___calender" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Calendar ID="calendar" runat="server" ShowGridLines="True" ShowDayHeader="True"
SelectionMode="Day" PrevMonthText="<<" NextMonthText=">>" DayNameFormat="Full"
DayHeaderStyle-HorizontalAlign="Center" Width="100%" TitleStyle-Font-Size="13px"
TodayDayStyle-BackColor="#ffffcc" DayStyle-Font-Size="13px" DayStyle-Font-Bold="True"
DayHeaderStyle-Font-Size="12px" OtherMonthDayStyle-ForeColor="#cccccc" OnDayRender="calendar_DayRender"
OnPreRender="calendar_PreRender">
<TodayDayStyle BackColor="#FFFFCC"></TodayDayStyle>
<OtherMonthDayStyle ForeColor="#CCCCCC"></OtherMonthDayStyle>
<DayStyle Font-Bold="True" Font-Size="13px"></DayStyle>
<DayHeaderStyle HorizontalAlign="Center" Font-Size="12px"></DayHeaderStyle>
<TitleStyle Font-Size="13px"></TitleStyle>
</asp:Calendar>
</div>
</form>
</body>
</html>
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;
using System.Threading;
using System.Data.OleDb;

public partial class ___TEST___calender : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void calendar_PreRender(object sender, EventArgs e)
{
//Thread t = Thread.CurrentThread;
//System.Globalization.CultureInfo c = (System.Globalization.CultureInfo)t.CurrentCulture.Clone();
//c.DateTimeFormat.DayNames = new string[] { "日", "一", "二", "三", "四", "五", "六" };
//c.DateTimeFormat.FirstDayOfWeek = DayOfWeek.Monday;
//t.CurrentCulture = c;
}
int preMonth, curMonth, nextMonth;
int[] preMonthArray, curMonthArray, nextMonthArray;
protected Calendar calendar1; //日历控件
protected void calendar_DayRender(object sender, DayRenderEventArgs e)
{
CalendarDay day = e.Day; //事件参数e,包含了年月日等信息
TableCell cell = e.Cell;

preMonth = day.Date.Month;
curMonth = (preMonth + 1 > 12) ? 1 : (preMonth + 1);
nextMonth = (curMonth + 1 > 12) ? 1 : (curMonth + 1);

curMonthArray = getBlogArray(day.Date.Year, curMonth);
preMonthArray = getBlogArray(day.Date.Year, preMonth);
nextMonthArray = getBlogArray(day.Date.Year, nextMonth);

int j = 0;
if (day.Date.Month.Equals(preMonth))
{
while (preMonthArray[j] != 0)
{
if (day.Date.Day == preMonthArray[j])
{
cell.Controls.Clear();
cell.Controls.Add(new LiteralControl("<a href='showBlog.aspx?tid=" + day.Date.Year.ToString() + day.Date.Month.ToString() + day.Date.Day.ToString() + "' style='color:#0000ff' target='main'>" + day.Date.Day.ToString() + "</a>"));
cell.Controls.Add(new LiteralControl("<br> 哈哈哈"));
}
j++;
}
}
else if (day.Date.Month.Equals(nextMonth))
{
while (nextMonthArray[j] != 0)
{
if (day.Date.Day == nextMonthArray[j])
{
cell.Controls.Clear();
cell.Controls.Add(new LiteralControl("<a href='showBlog.aspx?tid=" + day.Date.Year.ToString() + day.Date.Month.ToString() + day.Date.Day.ToString() + "' style='color:#0000ff' target='main'>" + day.Date.Day.ToString() + "</a>"));
}
j++;
}
}
else if (day.Date.Month.Equals(curMonth))
{
while (curMonthArray[j] != 0)
{
if (day.Date.Day == curMonthArray[j])
{
cell.Controls.Clear();
cell.Controls.Add(new LiteralControl("<a href='showBlog.aspx?tid=" + day.Date.Year.ToString() + day.Date.Month.ToString() + day.Date.Day.ToString() + "' style='color:#0000ff' target='main'>" + day.Date.Day.ToString() + "</a>"));
}
j++;
}
}
}
protected int[] getBlogArray(int year, int month)
{
int[] array = new int[31];
int i;
for (i = 0; i < 31; i++)
array[i] = 3;
i = 0;
OleDbConnection conn = new OleDbConnection(ConfigurationManager.ConnectionStrings["LocalXoyozoConnectionString"].ToString());
conn.Open();
OleDbCommand cmd = new OleDbCommand("SELECT [posttime] FROM [blogdata] WHERE month([posttime])=@month AND year([posttime])=@year", conn);
cmd.Parameters.Add("@month", OleDbType.Integer, 2, "month");
cmd.Parameters["@month"].Value = month;
cmd.Parameters.Add("@year", OleDbType.Integer, 2, "year");
cmd.Parameters["@year"].Value = year;

OleDbDataReader r = cmd.ExecuteReader();
while (r.Read())
{
array[i++] = r.GetDateTime(0).Day;
}
r.Close();
conn.Close();
return array;
}
}
6,147

我们在用数据控件的时候,一般会在 .aspx 页面生成如单向绑定

Text='<%# Eval("title") %>'

 

或双向绑定

Text='<%# Bind("title") %>'

 

之类的绑定代码,如果我们必需对它进行进一步处理,譬如取得的“产品分类的ID”,我想显示为“产品分类的名称”,或者格式化时间显示

等等。

如果只是连接字符串可以这样处理

Text='<%# Eval("title", "标题为:{0}") %>'

 

如果是通过一个方法去改变绑定值,则可以:

Text='<%# Server.HtmlEncode(Eval("title","{0}")) %>'

 

这里可以套用任何自定义的方法。更可以实现绑定两个数据库字段的实现:

Text='<%# formatUrl(Eval("ID","{0}"),Eval("xArchive","{0}")) %>'
public string formatUrl(string id, string archive)
{

if (archive.Trim() != "")
{

return "/xsdn/archive/" + archive + ".aspx";
}

else
{
return "/xsdn/"+id+".aspx";
}
}

 

 

xoyozo 17 年前
4,734

研究了两个小时,确认了一个BUG。

平台:VS2005,VS2008 (VS2003未知)

Framework:2.0,3.5 (1.1未知)

首先跟我做一遍,非常简单:

一、在 VS 中新建网站;
二、已有 Default.aspx,再建 Default2.aspx;
三、在这两个网页的 Page_Load 事件上分别加上断点
四、在 Default2.aspx 中拖入一个 ImageButton,并设该页为起始页
五、运行。

这时可以发现,程序在两处断点的地方都会停下来,而这两上网页根本就没有任何关系,只是在同一级目录而已。

经测试,ImageMap 控件也有同样的现象,其它的就没一一去试了。

建议大家尽量用Button代替ImageButton。按照下面的做法可以把Button美化成和ImageButton一样的效果,甚至更棒!

方法如下:

给 Button 加上 CssClass 属性来写样式,或在App_Themes 的 .skin 文件中定义 Button 的属性

<asp:Button runat="server" CssClass="ButtonStyle" />

 

然后在 .css 文件中处理它的样式,例如:

 

.ButtonStyle {
border:0;
color: #FFFFFF;
font-size: 14px;
font-weight:bold;
text-align: center;
vertical-align:middle;
line-height:27px;
height: 27px;
width: 77px;
background-color: transparent;
background-image: url(Images/button.gif);/*背景*/
background-position: center center;
}

 

这样就可以了,这时你会发现写在 Button 上的 Text 会随着你的鼠标按下而偏移,这个效果是不是 ImageButton 所没有的呢?

xoyozo 17 年前
5,175

需要 URLRewriter.dll,它可以在微软官方下载到:取出Bin里面的文件

接下来配置 Web.Config 文件:

在 <configSections> 节点下添加:

<section name="RewriterConfig" type="URLRewriter.Config.RewriterConfigSerializerSectionHandler, URLRewriter" />

在 <configuration> 节点下添加:

<RewriterConfig>
<Rules>
<RewriterRule>
<!--测试-->
<LookFor>~/(\d{2})/(\d{2})\.aspx</LookFor>
<SendTo>~/Default.aspx?m=$1&amp;d=$2</SendTo>
</RewriterRule>
</Rules>
</RewriterConfig>

在 <httpHandlers> 节点下添加:

<add verb="*" path="*.aspx" type="URLRewriter.RewriterFactoryHandler, URLRewriter" />


完成以上步骤即可以实现URL重写的。但是它只能实现 ~/11/11.aspx~/Default.aspx?m=11&d=11 的重写,如果要实现 ~/11/11.html~/Default.aspx?m=11&d=11 的重写,那么需要通过设置 IIS 来实现 .html 文件的筛选。(适合 IIS5 IIS6,在 IIS7 中不用这么麻烦,具体见本文末尾的链接,scott 的文章)

进入:Internet 信息管理服务 -》网站属性 -》主目录 -》配置 -》映射 -》添加 -》把扩展名 .html 映射到 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll。

然后在 <httpHandlers> 节点中,把 *.html 也交给 URLRewriter 处理就行了。

OK,试试看,访问 ~/11/11.html 确实是 ~/Default.aspx?m=11&d=11 的内容,可是只要 postback 一下,地址栏又显示实际路径了。只要在你的/app_browsers文件夹里添加一个.browser文件,注册使用一个控件适配类即可输出新的action属性。

 

 

 

你可在这里查看一个我创建的样例实现,其展示了该如何实现与URL重写协作的表单控件适配器(Form Control Adapter)

 

参考:http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx
译文:http://blog.joycode.com/scottgu/archive/2007/03/01/94004.aspx

xoyozo 17 年前
4,608