Winform版微博管理工具


本文內容導讀:

通過對winform微博管理工具,來記錄一些容易被忽視,而且很有趣的東西,比如:

1、xslt根據xml內容生成html文檔,並且里面一些比較寫法注意點等

2、xslt中調用C#方法

3、xslt中引入js的一些框架

4、js調用winform后台方法及winform調用js的方法(以webbrowser為媒介)

FeedDemon這個工具基本也是js和winform的互調;

    TX的QQ廣告太多,所以改用TM,之前QQ集成了騰訊微博,但改QQ為TM后,發現TM對微博的支持不太理想;但本人在中午飯后閑暇之時,喜歡看看微博和文章;但又不太喜歡每次刷網頁,麻煩;本來想去網上找個PC(winform)版本的騰訊微博,結果沒有,無奈,想到之前騰訊提供API了,所以去看了看騰訊微博開發平台;下面說重點,如何解決winform中對xml的解析問題;

   實現調用騰訊API的問題,在微博開發平台[http://wiki.open.t.qq.com/index.php]中可以查閱相關信息,里面有提供C#版本的SDK源文件和調用實例;所以在調用這塊我不多做解釋,我們只要通過API把相應的數據拿到程序里面,那么API就調用成功,剩下的就是我們程序自己內部交互的問題了;

基本上也就這么個小工具,目前支持的功能暫時只有騰訊微博,新浪微博正在准備開發中,可以支持長微博發送(大於140字自動轉圖片上傳到騰訊微博);

我們從調用API拿到數據開始說起,因為調用API騰訊已經說的很詳細,而且還有示例代碼;

首先紅色區域是一個webBrowser控件其他的都是winform里面的常用控件;大致實現如下

1、 首先通過API拿到xml數據,並且保存為本地的xml

View Code
statuses st = new statuses(oauthKey, "xml");
string ret = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";
ret += st.home_timeline(0, 0, 20);
//保存為本地xml
File.Delete(path + "\\temp.xml");
FileStream fs = new FileStream("temp.xml", FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(fs);
sw.Write(ret);
sw.Close();
fs.Close();

2、 現在API取數基本就完了,剩下的就是我們解析這個xml了並展示數據的問題了,我們使用xslt來解析xml為html文件

    a、 先看cs文件中將用xslt解析xml文件為html的代碼

View Code
string path = Application.StartupPath;
XslCompiledTransform trans = new XslCompiledTransform();
trans.Load("temp.xslt");
trans.Transform("temp.xml", "temp.html");
path = path + "\\temp.html";
wbContent.Visible = true;
if (wbContent.Url == null)
{
    wbContent.Url = new Uri(path);
}
wbContent.Refresh();

     b、 然后就是temp.xslt這個文件了;鄙人之前寫過一個簡單的xslt解析的簡單文章[http://www.cnblogs.com/RegicideGod/archive/2012/08/07/2627436.html],我們此處也用xslt來解析xml;看來前面的文件,這里的具體我也不全部放代碼來;直接說問題和解決方法吧;

騰訊提供的xml中的時間是時間戳,就是C#中[DateTime.Now.Ticks]的這個東西,我們在xslt中如何將時間戳轉換為時間?在網上搜了下代碼(網上有相關代碼,寫的不太詳細或不全),需要修改下cs文件中,加載xstl時候的參數設置,就是a步中修改為

View Code
StringBuilder sbXml = new StringBuilder();
StringWriter stringWriter = new StringWriter(sbXml);
XmlTextWriter xmlTextWriter = new XmlTextWriter(stringWriter);

//設置可以執行腳本函數
XsltSettings settings = new XsltSettings();
settings.EnableDocumentFunction = true;
settings.EnableScript = true;

//設置xslt可以包含外部的xslt文件
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
string path = Application.StartupPath;
XslCompiledTransform trans = new XslCompiledTransform();
trans.Load("temp.xslt", settings, resolver);
trans.Transform("temp.xml", "temp.html");

path = path + "\\temp.html";
wbContent.Visible = true;
if (wbContent.Url == null)
{
     wbContent.Url = new Uri(path);
}
wbContent.Refresh();

然后在XSLT的頭部這么寫

View Code
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:csfun="urn:csharp-functions" exclude-result-prefixes="msxsl">

  <xsl:output method="html" indent="yes"/>
  <xsl:include href="fun.xslt"/>

大致的意思是讓xslt文件可以調用csharp-function

然后fun.xslt中就可以這么來寫,將xml中的時間戳在xslt中調用C#方法來轉換成時間了

View Code
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:csfun="urn:csharp-functions" exclude-result-prefixes="msxsl">
  <msxsl:script implements-prefix="csfun" language="C#">
    <![CDATA[        
         public string CheckDate(string tm)
         {
            string timeStamp = tm;
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            DateTime dtResult = dtStart.Add(toNow);
            return dtResult.ToString();
         }
         ]]>
  </msxsl:script>
</xsl:stylesheet>

在來看下調用CheckDate方法

  “發表時間: <xsl:value-ofselect="csfun:CheckDate(timestamp)"/>”

就可以將xml中timestamp的值傳到剛才的c#方法中,然后接收返回值了;網上還有一些代碼是傳到JS中處理,好像大多數都沒提到要設置XsltSettings可以執行腳本函數

我們也一定要設置b步驟中的加載xslt轉換xml為html的方法;

還有一個小問題是xslt中寫img標簽和a標簽

View Code
<xsl:if test="image!=''">
              <a target="_blank" style="color:#999;">
                <xsl:attribute name="href">
                  <xsl:value-of select="image"/>/2000
                </xsl:attribute>
                <img src="{image}/120" border="0" />
              </a>
</xsl:if>

Img標簽中src可以直接指定xml的image值就可以了;不用xsl:value-of來查找了;騰訊微博中,圖片只給了路徑,沒有給圖片大小,需要自己手動填寫,/120是尺寸為120大小的圖片/2000一般是指原圖

   以上代碼就可以實現基本的從微博拿到數據存儲為xml在通過xslt轉成html顯示到webbrowser上面,就完成了整個微博的內容顯示,但最重要的是需要有交互,就是對某一條微博進行評論和回復;每一個條微博右下角都會對應一個轉播,評論,密語等功能操作,因為我們要通過生成的html中獲取選中的那一條的微博信息,然后彈出一個提示框,讓用戶輸入文字信息,進行評論;

這個界面(比較齪的界面)就是點擊某一條微博的時候,彈出一個層的效果,然后輸入文字信息點確定后,就會調用后台方法,通過API提交到騰訊服務器;

下面接說問題,在xslt模板生成的html中,是沒有生成頭標簽的,但是我們這個地方用了一個基於jquery彈出層框架,需要導入jquery框架等,所以需要在html頭部生一個標簽就是經常看到容易被忽略的

<!DOCTYPE html>

雖然我們寫的是html,但是我們要指定這個文檔是html才行,不然webbrowser顯示html帶引入js時會報錯,在xslt模板中我們導入上面一句話的寫法是

 <xsl:template name="DOCTYPE">
    <![CDATA[<!DOCTYPE html>]]>
  </xsl:template>

然后在<html>的上面寫上這么一句話,就相當於寫了<!DOCTYPE html>這個東西

<xsl:value-of select="document('')/*/xsl:template[@name='DOCTYPE']/node()" disable-output-escaping="yes"/>

JS的引入問題解決了,剩下的就是點擊頁面的確定把html頁面上的內容傳到form窗體上面,那么現在的問題就是js調用winform方法,在bs開發中js調用后台方法,就是ajax但這里不行,沒有IIS服務器的配合,行不通;繼續百度加谷歌,發現webbrowser給我們提供了便利,就是可以讓在webbrowser中的html通過js調用winform中的后台方法;我們來看下吧

a、指定主窗體類可以讓webbrowser回調窗體中的方法

View Code
//指定js可以回調webBrowser中的方法
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public partial class FrmMain : Form
    {
        public FrmMain()
        {}
         private void frmMain_Load(object sender, EventArgs e)
        {
           wbContent.ObjectForScripting = this;  //wbContent為webBrowser控件
        }
}

b、在窗體中寫好評論一條微博的方法

View Code
//評論一條微博
        public void Comments(string conText, string reid,string flag)
        {
            conText = conText == "" ? " " : conText;
            t tw = new t(oauthKey, "xml");
            string ret = tw.comment(conText, "", "", "", reid);
            if ("true".Equals(flag.ToLower())) 
            {
                BroadCast(conText, reid);
            }
        }

c、在js中的調用如下

View Code
//評論一條微博
        function Comments(reid)
         {
     
             //alert(conText);
            var con='<div style="width:'+(_iwid*0.7+25)+'px;height:'+_ihei*0.5+'px;margin-left:-8px;margin-top:-5px;">';
            con+='<textarea cols="80" style="margin-left:5px;margin-top:-5px;" rows="6" id="sendContent"></textarea><br/>您將評論:<br/>'+conText;
            con+='<br/><input type="checkbox" id="ch">一並轉播';
            con+='</div>';
         
         
           $.dialog({
            width:_iwid*0.7,
            height:_ihei*0.5,
            lock: true,
            title:'評論',
            background: '#DCE2F1', /* 背景色 默認的遮罩背景色為:#DCE2F1淺藍護眼色 */
            opacity: 0.5,       /* 透明度 */
            content: con,
            ok: function () {
            window.external.Comments($("#sendContent").val()+" ",reid,$("#ch")[0].checked);
             return true;
            },
            cancel: true
            });
         }

最重要的是標紅的那句話,是在js中調用winform后台的Comments方法,並且把參數傳到后台,今天消息處理;

當然還有在winform中通過webbrowser來調用js方法

//調用JS
        private void btnAddFace_Click(object sender, EventArgs e)
        {
            wbContent.Document.InvokeScript("scriptFunc", new String[] { "這是winform調用腳本方法" });
        }

到這里基本就完成了,主要是通過業務來講解一些簡單的技術問題;這些東西並不是很難理解,只是容易被忽視;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM