Case by Case..

Wang Ting's Tech Blog
随笔 - 40, 评论 - 250, 引用 - 12

导航

关于

勿发广告,谢谢配合

标签

每月存档

最新留言

广告

.Net 中的日志 (log file)

Useful Logging Options in .Net:

http://blog.joycode.com/tingwang/articles/80349.aspx

持续更新中……这可能是我写过的所有东西中最有用的一样,就看识不识货了……如果有补充,请留言,谢谢……

posted on 2006-12-01 13:27:00 by TingWang  评论(4) 阅读(7377)

.Net 2.0 Web Browser control - Interaction between the managed code and the HTML DOM

I am posting this as a small sample I worked for MCS. It demonstrate some bacic usages of .Net 2.0 WinForm WebBrowser control:

 

1. How we can hook up the HTML events with managed code.

2. How to get the current element being edited in the WebBrowser, either by mouse or by keyborad typing.

3. How we can identify the tags in the DOM document.

 

===========================Form1.cs===========================

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Xml;

using System.Xml.Xsl;

using System.Runtime.InteropServices;

 

namespace WebBrowserSample

{

            public partial class Form1 : Form

            {

                        public Form1()

                        {

                                    InitializeComponent();

                        }

 

                        // Holding the XML document.

                        private XmlDocument xdoc = new XmlDocument();

                        // Holding the XmlElement (e.g. <food>) from the XmlDocument being edited.

                        private XmlElement currentEditingXMLElement;

                        // Holding the HtmlElement (e.g. <div> with foodid attribute) from the HtmlDocument in the WebBrowser control.

                        private HtmlElement currentEditingHTMLElement;

 

                        [DllImport("user32.dll")]

                        public static extern bool GetCaretPos(ref Point pt);

 

                        private void button1_Click(object sender, EventArgs e)

                        {

                                    // Routine work. Load the XML into the control as well as the XmlDocument.

                                    // No need to apply XSLT further as the XML already specifies so with "xml-stylesheet".

                                    webBrowser1.Navigate(Application.StartupPath + "\\data.xml");

                                    xdoc.Load(Application.StartupPath + "\\data.xml");

                                    webBrowser1.Document.Click += new HtmlElementEventHandler(Document_Click);

                                    mshtml.IHTMLDocument2 hdoc = (mshtml.IHTMLDocument2)webBrowser1.Document.DomDocument;

                                    hdoc.designMode = "On";

                                    button1.Enabled = false;

                                    webBrowser1.Document.MouseMove += new HtmlElementEventHandler(Document_MouseMove);

 

                                    while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)

                                    {

                                                Application.DoEvents();

                                    }

 

                                   webBrowser1.Document.AttachEventHandler("onkeydown", new EventHandler(this.Document_KeyDown));

                        }

 

                        void Document_KeyDown(object sender, EventArgs e)

                        {

                                    Point p = new Point(0, 0);

                                    bool bResult = GetCaretPos(ref p);

                                    HtmlElement he = webBrowser1.Document.GetElementFromPoint(p);

                                    Console.WriteLine(he.InnerText);

                        }

 

                        // Holding the reference of the previous element that mouse moves over.

                        private HtmlElement previousMovedElement;

 

                        void Document_MouseMove(object sender, HtmlElementEventArgs e)

                        {

                                    // Get the current element under mouse cursor

                                    HtmlElement movingElement = webBrowser1.Document.GetElementFromPoint(e.MousePosition);

                                    // Is the element the same one as we recorded previously? If yes, we just ignore it.

                                    if (movingElement != previousMovedElement)

                                    {

                                                // The previous element we move over is a HTML span and now we are moving out of it.

                                                if ((previousMovedElement != null) && (previousMovedElement.TagName.ToLower() == "span"))

                                                {

                                                            // Restore the color for the previous span element.

                                                            mshtml.HTMLSpanElement previousSpan = (mshtml.HTMLSpanElement)previousMovedElement.DomElement;

                                                            object objColor = previousSpan.getAttribute("oldColor", 0);

                                                            string strColor = (objColor != null) ? objColor.ToString() : "";

                                                            if (!string.IsNullOrEmpty(strColor))

                                                                        previousSpan.style.color = strColor;

                                                            else

                                                                        previousSpan.style.removeAttribute("color", 0);

                                                }

                                                // We are moving to a span element.

                                                if (movingElement.TagName.ToLower() == "span")

                                                {

                                                            // Let's remember its current color, using an additiona attribute "oldColor":

                                                            mshtml.HTMLSpanElement span = (mshtml.HTMLSpanElement)movingElement.DomElement;

                                                            if (span.style.color != null)

                                                                        span.setAttribute("oldColor", span.style.color.ToString(), 0);

                                                            else

                                                                        span.setAttribute("oldColor", "",0);

                                                            span.style.color = "blue";

                                                }

                                                // Remember the last element we move over, no matter it is a span or not.

                                                previousMovedElement = movingElement;

                                    }

                        }

 

                        void Document_Click(object sender, HtmlElementEventArgs e)

                        {

                                    // Get the element being clicked.

                                    HtmlElement clickedElement = webBrowser1.Document.GetElementFromPoint(e.MousePosition);

                                    string id = null;

 

                                    // Go up in the hierarchy until we locate the "div" with "foodid" attribute.

                                    // Then we can find out the details from the XML with the same ID.

                                    while (clickedElement.Parent != null)

                                    {

                                                id = clickedElement.GetAttribute("foodid");

                                                if (!string.IsNullOrEmpty(id))

                                                {

                                                            currentEditingHTMLElement = clickedElement;

                                                            break;

                                                }

                                                else

                                                            clickedElement = clickedElement.Parent;

                                    }

 

                                    // Make sure that we find the id.

                                    if (!string.IsNullOrEmpty(id))

                                    {

                                                // XPath query for locating the food element with same id from the XmlDocument.

                                                currentEditingXMLElement = (XmlElement)(xdoc.SelectSingleNode("//food[@id=" + id + "]"));

                                                // Create the wrapper class, so that we can associate it with the PropertyGrid.

                                                FoodClass currentEditingFoodClass = new FoodClass();

                                                currentEditingFoodClass.Description = currentEditingXMLElement.SelectSingleNode("description").InnerText;

                                               currentEditingFoodClass.Name = currentEditingXMLElement.SelectSingleNode("name").InnerText;

                                                currentEditingFoodClass.Price = currentEditingXMLElement.SelectSingleNode("price").InnerText;

                                                currentEditingFoodClass.Calories = int.Parse(currentEditingXMLElement.SelectSingleNode("calories").InnerText);

                                                currentEditingFoodClass.Id = id; //This property is unused actually.

                                                // Associate the callback routine, so that we can update the HTML view.

                                                currentEditingFoodClass.ContentChanged += new EventHandler(currentEditingFoodClass_ContentChanged);

                                                propertyGrid1.SelectedObject = currentEditingFoodClass;

                                    }

                                    richTextBox1.Text = clickedElement.OuterHtml;

                        }

 

                        void currentEditingFoodClass_ContentChanged(object sender, EventArgs e)

                        {

                                    ConentChangedEventArgs ce = (ConentChangedEventArgs)e;

                                    string field = ce.Field.ToLower();

                                   

                                    // Update the content in the XmlDocument

                                    XmlNode xmlNodeToUpdate = currentEditingXMLElement.SelectSingleNode(field);

                                    xmlNodeToUpdate.InnerText = ce.NewValue;

 

                                    // Update the HTML view

                                    // Get all span elements from under the current div.

                                    HtmlElementCollection hec = currentEditingHTMLElement.GetElementsByTagName("span");

                                    foreach (HtmlElement he in hec)

                                    {

                                                // Is this span the one we are looking for?

                                                if (he.GetAttribute("field") == field)

                                                {

                                                            switch (field)

                                                            {

                                                                        // Special handling for price and calories

                                                                        case "price":

                                                                                    he.InnerText = " - " + ce.NewValue;

                                                                                    break;

                                                                        case "calories":

                                                                                    he.InnerHtml = "(" + ce.NewValue + " calories per serving)";

                                                                                    break;

                                                                        default:

                                                                                    he.InnerText = ce.NewValue;

                                                                                    break;

                                                            }

                                                            break;

                                                }

                                    }

                        }

            }

}

===========================Form1.Designer.cs===========================

namespace WebBrowserSample

{

            partial class Form1

            {

                        /// <summary>

                        /// Required designer variable.

                        /// </summary>

                        private System.ComponentModel.IContainer components = null;

 

                        /// <summary>

                        /// Clean up any resources being used.

                        /// </summary>

                        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>

                        protected override void Dispose(bool disposing)

                        {

                                    if (disposing && (components != null))

                                    {

                                                components.Dispose();

                                    }

                                    base.Dispose(disposing);

                        }

 

                        #region Windows Form Designer generated code

 

                        /// <summary>

                        /// Required method for Designer support - do not modify

                        /// the contents of this method with the code editor.

                        /// </summary>

                        private void InitializeComponent()

                        {

                                    this.webBrowser1 = new System.Windows.Forms.WebBrowser();

                                    this.button1 = new System.Windows.Forms.Button();

                                    this.richTextBox1 = new System.Windows.Forms.RichTextBox();

                                    this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();

                                    this.SuspendLayout();

                                    //

                                    // webBrowser1

                                    //

                                    this.webBrowser1.Location = new System.Drawing.Point(12, 12);

                                    this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);

                                    this.webBrowser1.Name = "webBrowser1";

                                    this.webBrowser1.Size = new System.Drawing.Size(473, 494);

                                    this.webBrowser1.TabIndex = 0;

                                    //

                                    // button1

                                    //

                                    this.button1.Location = new System.Drawing.Point(491, 12);

                                    this.button1.Name = "button1";

                                    this.button1.Size = new System.Drawing.Size(200, 29);

                                    this.button1.TabIndex = 1;

                                    this.button1.Text = "Load XML";

                                    this.button1.UseVisualStyleBackColor = true;

                                    this.button1.Click += new System.EventHandler(this.button1_Click);

                                    //

                                    // richTextBox1

                                    //

                                    this.richTextBox1.Location = new System.Drawing.Point(491, 47);

                                    this.richTextBox1.Name = "richTextBox1";

                                    this.richTextBox1.Size = new System.Drawing.Size(200, 136);

                                    this.richTextBox1.TabIndex = 2;

                                    this.richTextBox1.Text = "";

                                    //

                                    // propertyGrid1

                                    //

                                    this.propertyGrid1.Location = new System.Drawing.Point(491, 189);

                                    this.propertyGrid1.Name = "propertyGrid1";

                                    this.propertyGrid1.Size = new System.Drawing.Size(200, 317);

                                    this.propertyGrid1.TabIndex = 3;

                                    //

                                    // Form1

                                    //

                                    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

                                    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

                                    this.ClientSize = new System.Drawing.Size(720, 518);

                                    this.Controls.Add(this.propertyGrid1);

                                    this.Controls.Add(this.richTextBox1);

                                    this.Controls.Add(this.button1);

                                    this.Controls.Add(this.webBrowser1);

                                    this.Name = "Form1";

                                    this.Text = "Form1";

                                    this.ResumeLayout(false);

 

                        }

 

                        #endregion

 

                        private System.Windows.Forms.WebBrowser webBrowser1;

                        private System.Windows.Forms.Button button1;

                        private System.Windows.Forms.RichTextBox richTextBox1;

                        private System.Windows.Forms.PropertyGrid propertyGrid1;

            }

}

 

===========================FoodClass.cs===========================

 

using System;

using System.Collections.Generic;

using System.Text;

using System.ComponentModel;

 

namespace WebBrowserSample

{

            // Customized Event Argument for firing the content changed event.

            public class ConentChangedEventArgs : EventArgs

            {

                        public string Field; // Which field of the object has been changed.

                        public string NewValue;  // The new value.

            }

 

            // Wrapper class for a "Food". We need to associate this with PropertyGrid.

            public class FoodClass

            {

                        // Exposing an event for callback.

                        public event EventHandler ContentChanged;

 

                        // Internal method for raising the event.

                        private void OnContentChanged(object sender, EventArgs e) {

                                    if (ContentChanged != null)

                                    {

                                                ContentChanged(sender, e);

                                    }

                        }

 

                        private string mName;

                        [Category("Mandatory")]

                        public string Name

                        {

                                    get { return mName; }

                                    set {

                                                mName = value;

                                                ConentChangedEventArgs e = new ConentChangedEventArgs();

                                                e.Field = "Name";

                                                e.NewValue = value;

                                                OnContentChanged(this, e);

                                    }

                        }

 

                        private string mPrice;

                        [Category("Mandatory")]

                        public string Price

                        {

                                    get { return mPrice; }

                                    set {

                                                mPrice = value;

                                                ConentChangedEventArgs e = new ConentChangedEventArgs();

                                                e.Field = "Price";

                                                e.NewValue = value;

                                                OnContentChanged(this, e);

                                    }

                        }

 

                        private string mDescription;

                        [Category("Optional")]

                        public string Description

                        {

                                    get { return mDescription; }

                                    set {

                                                mDescription = value;

                                                ConentChangedEventArgs e = new ConentChangedEventArgs();

                                                e.Field = "Description";

                                                e.NewValue = value;

                                                OnContentChanged(this, e);

                                    }

                        }

 

                        private int mCalories;

                        [Category("Optional")]

                        public int Calories

                        {

                                    get { return mCalories; }

                                    set {

                                                mCalories = value;

                                                ConentChangedEventArgs e = new ConentChangedEventArgs();

                                                e.Field = "Calories";

                                                e.NewValue = value.ToString();

                                                OnContentChanged(this, e);

                                    }

                        }

 

                        //It seems that this property is not necessary here. I just leave it here.

                        private string mId;

                        [Browsable(false)]

                        public string Id

                        {

                                    get { return mId; }

                                    set { mId = value; }

                        }

            }

}

 

===========================simple.xsl===========================

<?xml version="1.0" encoding="ISO-8859-1"?>

<!-- Edited with XML Spy v4.2 -->

<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">

            <body style="font-family:Arial,helvetica,sans-serif;font-size:12pt;

        background-color:#EEEEEE">

                        <!--

                        I encapsulate each food into a "div" with an attribute "foodid".

                        This will make life easier when we need to locate the HtmlElement and upate it when changes are made

                                    in the PropertyGrid.

                        -->

                        <xsl:for-each select="breakfast_menu/food">

                                    <div>

                                                <xsl:attribute name="foodid">

                                                            <xsl:value-of select="@id"/>

                                                </xsl:attribute>

                                                <div style="background-color:teal;color:white;padding:4px">

                                                            <!--

                                                                        For the properties of the food, they will be displayed in html span.

                                                                        Again I inject an invisible attribute (e.g. "field") to identify the property displayed by the span.

                                                            -->

                                                            <span style="font-weight:bold;color:white" field="name">

                                                                        <xsl:value-of select="name"/>

                                                            </span>

                                                            <span field="price">

                                                                        - <xsl:value-of select="price"/>

                                                            </span>

                                                </div>

                                                <div style="margin-left:20px;margin-bottom:1em;font-size:10pt">

                                                            <span field="description">

                                                                        <xsl:value-of select="description"/>

                                                            </span>

                                                            <span style="font-style:italic" field="calories">

                                                                        (<xsl:value-of select="calories"/> calories per serving)

                                                            </span>

                                                </div>

                                    </div>

                        </xsl:for-each>

            </body>

</html>

 

===========================data.xml===========================

<?xml version="1.0" encoding="ISO-8859-1"?>

<?xml-stylesheet type="text/xsl" href="simple.xsl" ?>

<breakfast_menu>

            <!-- Assign each food a unique id-->

            <food id ="0">

                        <name>Belgian Waffles</name>

                        <price>$5.95</price>

                        <description>two of our famous Belgian Waffles with plenty of real maple syrup</description>

                        <calories>650</calories>

            </food>

            <food id="1">

                        <name>Strawberry Belgian Waffles</name>

                        <price>$7.95</price>

                        <description>light Belgian waffles covered with strawberries and whipped cream</description>

                        <calories>900</calories>

            </food>

            <food id="2">

                        <name>Berry-Berry Belgian Waffles</name>

                        <price>$8.95</price>

                        <description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>

                        <calories>900</calories>

            </food>

            <food id="3">

                        <name>French Toast</name>

                        <price>$4.50</price>

                        <description>thick slices made from our homemade sourdough bread</description>

                        <calories>600</calories>

            </food>

            <food id="4">

                        <name>Homestyle Breakfast</name>

                        <price>$6.95</price>

                        <description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>

                        <calories>950</calories>

            </food>

</breakfast_menu>

 

 

posted on 2006-12-01 13:02:00 by TingWang  评论(0) 阅读(1951)

TFS恢复数据库后需要清Cache

MVP 王兴明的blog中已经提到了……
http://blog.joycode.com/mango/archive/2006/11/13/86530.aspx

在做完MSDN的步骤之后还需要删除下面目录中的内容,否则可能会出现文件名和内容混乱:

C:\Program Files\Microsoft Visual Studio 2005 Team Foundation Server\Web Services\VersionControl\Data

How to: Restore Team Foundation Server Data
http://msdn2.microsoft.com/en-us/library/ms252458(VS.80).aspx

文档到现在似乎还是没有更新……

关于TFS Source Control的缓存设置,下面的文档里有详细描述:

How to: Change Cache Settings for an Application-Tier Server
http://msdn2.microsoft.com/en-us/library/ms400793(VS.80).aspx

虽然已经有人写过了,由于问题是我处理的,在这里还是记上一笔……

posted on 2006-12-01 00:01:00 by TingWang  评论(3) 阅读(1690)

Powered by: Joycode.MVC引擎 0.5.2.0