诸如访问http://localhost/swsample/SysPage/ShowView.aspx?view=Calculator
我们看看ShowView.aspx对应的后台类ShineWay.AjaxComm.GateWay.ShowView,它是一个Page,在他的Page_Load事件中我们看到
this._viewName = this.Request.QueryString["View"];
//为了防止Session发生变化(新的sessionID),在Session中加点东西
this.Session.Add("ID",this._viewName);
在这里类变量应该得到赋值"Calculator",接着在Render中我们看到:
ViewProxy proxy = this.GetViewProxy();
writer.WriteLine("<html>");
writer.WriteLine("<head>");
writer.WriteLine("<title>AjaxCRM</title>");
writer.WriteLine("<script src=/"../Core/lib.js/"></script>");
writer.WriteLine(String.Format("<link href=/"../Style/{0}/" _fcksavedurl="/"../Style/{0}/"" type=/"text/css/" rel=/"stylesheet/">",
proxy.GetViewStyle(this._viewName)));
writer.WriteLine("</head>");
writer.WriteLine("<body>");
//页面正体
writer.WriteLine(proxy.GetViewContent(this._viewName));
writer.WriteLine("</body>");
writer.WriteLine("</html>");
因此我们知道页面的正文部分完全由类ViewProxy根据当前的View名称产生:
if(StringUtils.isNullOrEmpty(viewName))
return String.Empty;
BaseView view = this.GetView(viewName);
if(view == null) return "Can't Find View:"+viewName;
try
{
return view.GenerateHtml();
}catch(System.Exception e)
{
return e.Message+"<br><br>"+e.Source;
}
从这里我们看到,其实根本上是Proxy根据View的名称产生对应的BaseView对象(继承了BaseView),类和名称的对应关系在配置文件Views.config中有详细的表现。那么BaseView如何正确产生页面的HTML内容呢?
在上述代码中我们看到他在于view.GenerateHtml();
GenerateHtml:
BaseControl control = SessionManager.Instance.UpdateControl(this.SessionID, this.Control);
if(null == control) throw new AjaxException("没有找到控制器!");
return this.GetComponents(control);
也就是说最终产生的HTML是根据control中的控件来生成的。这剩下的代码可以顺藤摸瓜进行察看。我们看看控制器中是如何编写的:
/// <summary>
/// Calculator 的摘要说明。
/// </summary>
public class Calculator:BaseControl
{
private AjaxTextBox display;
private AjaxButton[] buttons;
private char[] texts = {'0','1','2','3','4','5','6','7','8','9','+','-','*','/','(',')','=','C'};
/// <summary>
/// 初始化当前控制其中的组件
/// 并且设置界面各个控件初始值
/// </summary>
public override void InitView()
{
this.display = new AjaxTextBox();
this.AddComponent(this.display);
this.NewButtons();
}
/// <summary>
/// 建立Buttons
/// </summary>
private void NewButtons()
{
this.buttons = new AjaxButton[this.texts.Length];
for(int i=0,size=this.texts.Length;i<size;i++)
{
this.buttons[i] = new AjaxButton();
this.buttons[i].Value = this.texts[i];
this.buttons[i].OnClick += new ClickEventHandler(this.BtnClick);
this.buttons[i].StyleClass = "ButtonCSS";
this.AddComponent(this.buttons[i]);
}
}
/// <summary>
/// 按钮点击
/// </summary>
/// <param name="com"></param>
private void BtnClick(IComponent com)
{
if(com.Value.ToString().Equals("="))
{
MathematicalOperator oper = new MathematicalOperator(this.display.Value.ToString(),new HybridDictionary(0));
if(oper.Error == "0")this.display.Value = oper.Result;
else this.display.Value = oper.Error;
}else if(com.Value.ToString().Equals("C"))
{
this.display.Value = "";
}
else
{
this.display.Value = this.display.Value.ToString()+ com.Value.ToString();
}
}
}
俨然一个没有拖拽界面的winform事件编程,其中关键的是每个定义的控件都需要调用函数this.AddComponent
其余的部分就是对控件设置初始化数据和事件编程了。
下一章:我将讲事件如何触发并进行处理。