台灣 IT 人的心聲,我們聽到了。微軟將於 2008 年 7 月 26 日,在京華城 B3 地心引力廣場,舉辦第一屆台灣系統管理者日。除慶祝活動外,微軟也將與您面對面對談;這天,是屬於你們的日子!
[SilverLight 2.0] 事件 Declaring Event Handlers
在Silverlight宣告事件的方式有兩種:
- 直接在XAML內部宣告 (優點:簡單明瞭, 缺點: 只能使用預設的參數, 不能再加參數)
- 在.cs裡面作宣告 (優點: 彈性大, 可以做變化; 缺點: 比較困難(吧~) )
第一種方式:
在XAML直接作宣告(eg. 在Page.xaml):
<Canvas Loaded=”Canvas_Loaded”>
<Button x:Name=”myButton” Content=”Hello”
Canvas.Left=”10″ Canvas.Top=”10″ />
</Canvas>
在Page.xaml.cs作處理:
private void Canvas_Loaded(object sender, RoutedEventArgs e)
{
theButton.Content = “Please Click Me”;
}
第二種方式
不需在XAML裡面宣告事件
<!– <Canvas Loaded=”Canvas_Loaded”> –>
<Canvas >
<Button x:Name=”theButton” Content=”I’m Indented!”
Canvas.Left=”150″ Canvas.Top=”20″ />
<CheckBox x:Name=”RushOrder” Content=”Rush”
Canvas.Left=”50″ Canvas.Top=”20″ FontSize=”18″ />
</Canvas>
而是直接在Page.xaml.cs的Page( ) Constructor動手腳~
public Page()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
/*throw new NotImplementedException(); 去掉這行 */
theButton.Click +=new RoutedEventHandler(theButton_Click); //事件1
RushOrder.Checked += new RoutedEventHandler(RushOrder_Changed); //事件2
RushOrder.Unchecked +=new RoutedEventHandler(RushOrder_Change); //事件3
}
void RushOrder_Changed(object sender, RoutedEventArgs e)
{
if (RushOrder.IsChecked == true)
{
RushOrder.Content = “RUSH”;
}
else
{
RushOrder.Content = “Rush”;
}
}
[SilverLight2] Layout Control介紹
在SilverLight中用來規劃整個版面Layout的Control主要有三種:
- Grid: 就像Table一樣, 將物件以行列的方式對齊
- StackPanel: 讓物件之間相對對齊, 如相鄰對齊或向上對齊
- Canvas: 用絕對對齊(absolute positioning) 的方式放置物件(與SilverLight 1.0相符)
Grid
Grid 在使用VS2008開啟新檔案的時候就已經存在XAML裡面了, 格式會長這個樣子:
<UserControl x:Class=”EasyGrid.Page”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
Width=”400″ Height=”300″>
<Grid x:Name=”LayoutRoot” Background=”White”>
</Grid>
你可以先規劃整個SilverLight App的框線, 以便之後的對齊作業, 定義的方式如下:
<Grid x:Name=”LayoutRoot” Background=”White”>
<Grid.RowDefinitions>
<RowDefinition Height=”50″ />
<RowDefinition Height=”30*” MaxHeight=”70″ />
<RowDefinition Height=”40*” MaxHeight=”70″ />
<RowDefinition Height=”*” MinHeight=”30″ MaxHeight=”50″ />
<RowDefinition Height=”Auto” MinHeight=”5″ MaxHeight=”30″ />
</Grid.RowDefinitions>
</Grid>
Height: 每一列的高度
MaxHeight: 能夠拉伸的最大高度 (* 表示以比例的方式定義高度, 兩倍高就是 2*)
MinHeight: 能夠拉伸的最小高度
StackPanel
Stack就是堆疊的意思, 使用StackPanel你可以將你的物件以左右堆疊或者上下堆疊的方式排列, 就像書本在書架上一樣. 它也是在SilverLight2.0經常使用的對齊工具. 下面以放置TextBlock, TextBox, CheckBox及Button 為例:
<StackPanel Background=”Beige” Orientation=”Vertical” >
<TextBlock Text=”Your name?”
HorizontalAlignment=”Left” Margin=”10,2,0,1″/>
<TextBox Width=”150″ Height=”30″
HorizontalAlignment=”Left” Margin=”10,2,0,1″/>
<Button Content=”Submit this information”
HorizontalAlignment=”Left”
Margin=”10,2,0,1″ Height=”30″ Width=”150″ />
<CheckBox Content=”With Zing!” HorizontalAlignment=”Left”
Margin=”10,2,0,1″ />
</StackPanel>
屬性:
Background: Stack背景的顏色
Orientation: 排列方向, Vertical是垂直
在StackPanel內部的物件Margin=”10,2,0,1″ 的Margin順序是左, 上, 右, 下.
[SilverLight2] TextBlock的屬性
SilverLight的Control有很多, 以後會逐一介紹其用法, 首先介紹TextBlock的屬性:
<TextBlock x:Name=”TestName” Grid.Row=”0″ Grid.Column=”0″ Text=”Testing Name: ” Margin=”5″ />
應用: TextBlock的使用方法跟.NET的Label Control很像, 就是專門顯示文字用的.
屬性:
Grid.Row, Grid.Column叫做Extended Properties, 功能是對齊週邊的Grid格線, 讓App看起來較整齊.
Text 功能就是顯示內部的文字.
Margin很有趣, 輸入不同數目的值就有不同的Margin效果.
Margin=”5″ : 表示 左, 右, 上, 下 都是空出5px.
Margin=”5,6″ : 表示 左右空出5px, 上下空出6px.
Margin=”5,6,7,8″: 表示 左5px, 上6px, 右7px, 下8px.
安裝SilverLight 2 BETA 2 Tools for Visual Studio 2008 的錯誤
如果您的安裝順序是:
1. Visual Studio 2008
2. SilverLight 2 BETA 2 Tools for Visual Studio 2008
應該可以安裝成功,
但如果安裝的順序是:
1. Visual Studio 2008
2. SilverLight 1.0 Runtime
3. SilverLight 2.0 Runtime
4. SilverLight 2 BETA 2 Tools for Visual Studio 2008
則會在安裝的時候出現ERROR. 經過測試, 要解決這個問題方法如下:
1. 控制台 > 新增與移除程式 > 將SilverLight 1.0, 2.0 的RUNTIME都徹底移除
2. 將Program Files 的 SilverLight, SilverLight SDK都移除乾淨.
3. 再安裝SilverLight 2 BETA 2 Tools for Visual Studio 2008 就可以成功了.
建議的安裝順序為:
1. Visual Studio 2008
2. Silverlight 2.0 Run time.
3. Expression Blend 2.5
4. Visual Studio 2008 SP1
5. silverlight_chainer.exe
[Visual C#]Params的應用: Method傳入參數同時可以是陣列與Integer?
當我們在撰寫物件導向程式的時候, 難免會需要將參數傳入Method裡面, 若傳入的參數是陣列, 格式如下:
static void Main(string[] args)
{int[] a = new int[2]{5,7};
Util util = new Util();
Console.WriteLine(util.Min(a));
}
class Util
{public int Min(int[] param)
{
if (param == null || param.Length == 0)
{
throw new ArgumentException(“Util.Min: not enough arguments”);
}int currentmin = param[0];
foreach (int i in param)
{
if (i < currentmin)
{
currentmin = i;
}
}return currentmin;
}}
這種寫法應該很直觀吧, 但如果傳入的參數是Integer豈不是出現Error? 要怎麼解決呢? 其實要解決這個問題非常簡單, 就是在Method的參數部分加入 “params”這個關鍵字, 寫法如下:
class Util
{public int Min(params int[] param)
{
if (param == null || param.Length == 0)
{
throw new ArgumentException(“Util.Min: not enough arguments”);
}int currentmin = param[0];
foreach (int i in param)
{
if (i < currentmin)
{
currentmin = i;
}
}return currentmin;
}}
這樣一來傳入的參數會經過compiler做以下的動作:
int min = Util.Min(first, second);
int[] array = new int[2];
array[0] = first;
array[1] = second;
int min = Util.Min(array);
你的主程式就可以彈性傳入參數, 夠方便吧?
static void Main(string[] args)
{int[] a = new int[2]{5,7};
Util util = new Util();
Console.WriteLine(util.Min(a));//可以傳入陣列型態的變數
int b = util.Min(2, 10); //同時可以傳入多個Integer
Console.WriteLine(b);
}
使用params有幾個注意事項:
Javascript的navigator.userAgent判斷使用者的瀏覽器版本是好方法嗎?
我們先把話說在前頭, Javascript的所有函數並不適用在所有的瀏覽器, 這個大家都贊同吧?
所以你一定會跟我一樣想先擷取使用者的瀏覽器版本, 看看它是用IE, MOZILLA還是Opera等等的, 但這樣的方法真的好用嗎? 老實說這是相當難維護的, 因為瀏覽器會一直更新, 如果你都用IF ELSE來判斷它的版本應該會要一直更新吧, 而且你又要怎麼判斷你的使用者會不會比你更快更新它的瀏覽器呢?
舊的方法如下:
javascript:alert(navigator.userAgent);
如果你使用IE7, 它會回傳給你: Mozilla 4.0/ …..
這樣的方法真的不是很好, 在這裡有個不錯的方式來判斷:
if (typeof featureName != “undefined”) {
// 程式碼
}
舉例如下:
if (typeof document.getElementById != “undefined”) {
alert(“getelembyid is supported”);} else {
alert(“no getelembyid support”);
}
我們要判斷瀏覽器是否支援getElementById 就可以直接用typeof document.xx != “undefined” 來判斷 如果使用者不支援這個函數你就可以再另外想辦法. 另外一種寫法如下:
var getElem = (typeof document.getElementById == “function”) ? true : false;
if (getElem) {
// 我們知道GetElementbyId是支援的,
// 所以我們就可以用它.
}
這樣是不是比較實際且容易維護呢?
Javascript 的addEventListener()及attachEvent()
大家都知道事件的用法就是當某個事件(狀況)被觸發了之後就會去執行某個Function, 尤其是Javascript, 在當紅AJAX的催化下, 了解Javascript的Event用法更加重要, 在這裡就大概介紹一下Javascript的Event用法.
從W3C的發展時間軸來看, DOM(Document Object Model)的模型可以分為兩種, DOM 0 及 DOM 2. 從數字來看就可以知道DOM 0 當然是比較舊的協定, 我們可以從以下的表格來看:
DOM1 協定:
Event Name |
Description |
---|---|
onblur() |
The element has lost focus (that is, it is not selected by the user). |
onchange0 |
The element has either changed (such as by typing into a text field) or the element has lost focus. |
onclick0 |
The mouse has been clicked on an element. |
ondblclick() |
The mouse has been double-clicked on an element. |
onfocus() |
The element has gotten focus. |
onkeydown() |
A keyboard key has been pressed down (as opposed to released) while the element has focus. |
onkeypress() |
A keyboard key has been pressed while the element has focus. |
onkeyup() |
A keyboard key has been released while the element has focus. |
onload() |
The element has loaded (document, frameset, or image). |
onmousedown() |
A mouse button has been pressed. |
onmousemove() |
The mouse has been moved. |
onmouseout() |
The mouse has been moved off of or away from an element. |
onmouseover() |
The mouse has moved over an element. |
onmouseup() |
A mouse button has been released. |
onreset() |
The form element has been reset, such as when a form reset button is pressed. |
onresize() |
The window’s size has been changed. |
onselect() |
The text of a form element has been selected. |
onsubmit() |
The form has been submitted. |
onunload() |
The document or frameset has been unloaded. |
DOM2 的進化:
DOM 0 Event |
DOM 2 Event |
---|---|
onblur() |
blur |
onfocus() |
focus |
onchange() |
change |
onmouseover() |
mouseover |
onmouseout() |
mouseout |
onmousemove() |
mousemove |
onmousedown() |
mousedown |
onmouseup() |
mouseup |
onclick() |
click |
ondblclick() |
dblclick |
onkeydown() |
keydown |
onkeyup() |
keyup |
onkeypress() |
keypress |
onsubmit() |
submit |
onload() |
load |
onunload() |
unload |
新的DOM2 用法可以addEventListener()這個函數來觀察到:
addEventListener(event,function,capture/bubble);
參數event如上表所示, function是要執行的函數, capture與bubble分別是W3C制定得兩種時間模式,簡單來說capture就是從document的開始讀到最後一行, 再執行事件, 而bubble則是先尋找指定的位置再執行事件.
capture/bubble的參數是布林值, True表示用capture, False則是bubble.Windows Internet Explorer也有制定一種EventHandler, 是 attachEvent(), 格式如下:
window.attachEvent(“submit”,myFunction());
比較特別的是attachEvent不需要指定capture/bubble的參數, 因為在windows IE環境下都是使用Bubble的模式.這裡用圖像的Rollover例子來表現事件的用法:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”
“http://www.w3.org/TR/html4/strict.dtd“>
<html>
<head>
<title>Rollover</title>
<script type=”text/javascript”>function moveOver(imgObj) {
if (typeof window.addEventListener != “undefined”) {
imgObj.addEventListener(“mouseover”,function(){imgObj.src = imgObj.id +
“_over.png”;}, false);
imgObj.addEventListener(“mouseout”, function(){imgObj.src = imgObj.id +
“_default.png”;}, false);
} else {
imgObj.attachEvent(“onmouseover”,function(){imgObj.src = imgObj.id +
“_over.png”;});
imgObj.attachEvent(“onmouseout”, function(){imgObj.src = imgObj.id +
“_default.png”;});
}
}function rollover() {
var images = document.getElementsByTagName(“img”);
var roll = new RegExp (“rollover”);
var preload = [];
for (var i = 0; i < images.length; i++) {
if (images[i].id.match(roll)) {
preload[i] = new Image();
preload[i].src = images[i].id + “_over.png”;
moveOver(images[i]);
}
}
}
if (typeof window.addEventListener != “undefined”) {
window.addEventListener(“load”,rollover,false);
} else {
window.attachEvent(“onload”,rollover)
}
</script>
</head>
<body>
<p><img id=”rollover_home” name=”img_home” src=”rollover_home_default.png”
alt=”Home”></p>
<p><img id=”rollover_about” name=”img_about” src=”rollover_about_default.png”
alt=”About”></p>
<p><img id=”rollover_blog” name=”img_blog” src=”rollover_blog_default.png”
alt=”Blog”></p>
<p><img id=”logo” name=”img_logo” src=”logo.png” alt=”Braingia Logo”></p>
</body>
</html>
上述的 typeof window.addEventListener != “undefined” 程式碼可以判斷使用者的瀏覽器是否支援AddEventListener這個事件模型, 如果不支援就使用attachEvent.
W3C 及 IE 同時支援移除指定的事件, 用途是移除設定的事件, 格式分別如下:
W3C格式:
removeEventListener(event,function,capture/bubble);
Windows IE的格式如下:
detachEvent(event,function);
資料參考: Chapter 14 – Browsers and JavaScript, JavaScript Step by Step, by Steve Suehring
很棒的Javascript除錯程式
一直以來Javascript的除錯都是非常煩人的步驟, 最近發現有個很棒的程式, 在這裡跟大家分享,
FireBug
這是Open Source軟體, 且完全免費, 是個搭配Firefox的Plugin, 它可以圖像化您的程式碼, 包括了HTML, CSS, 及javascript, 您可以通過它來觀看所有網頁, 不干擾您的瀏覽, 您也可以隨時把它關掉. 最棒的是它直接幫你把程式碼劃分好, 再除錯方面非常方便. 它佔的空間也很小喔~
更過詳情可參考: http://getfirebug.com/
[Outlook Express] 郵件太大, 出現對話框要求你壓縮郵件, 但你又不想把郵件壓縮怎麼辦?
最近在處理用戶電腦時候遇到了以下的問題, 後來找到方法解決了, 在這裡做個紀錄:
處理錯誤碼: 0x800C0133
發生原因可參考: http://www.binbin.net/messages/qa_win_oe/0104.htm
我的解決方式:
Outlook Express有個天生的缺點, 就是當某個資料夾超過2G時便會在收件時出現錯誤訊息, 要求你先壓縮郵件, 以釋放空間, 但我個人是相當不建議把郵件壓縮起來, 因為往往會造成日後開不到, 那你2G的信就不見了(哭~)
可是, 如果你不壓縮, “收件匣”又沒有辦法再接收新的郵件, 怎麼辦呢?
我的作法如下:
1.關閉Outlook Express.
2. 到以下路徑:
C:\Documents and Settings\Administrator\Local Settings\Application Data\Identities\{1936D57C-EA58-4C14-9A09-D10B5B2BFCF5}\Microsoft\Outlook Express
3. 你就看到跟你的Outlook Express裡資料夾相同的.dbx檔, 包括了收件匣.dbx, 刪除的郵件.dbx, 寄件備份.dbx等等. 我們現在要做的事情就是把超過2G的”收件匣.dbx” 命名成其他的名字, 如: “收件匣1.dbx”.
4.再度打開Outlook Express, 你就會發現可以收信了! 而且收件匣這個資料夾裡面是空的. (囧….之前的信都去哪裡了?)
5. 不用擔心, 因為Outlook Express就是因為找不到原本的”收件匣.dbx”, 就自作主張幫你建立了一個新的 “收件匣.dbx”. 新的”收件匣.dbx”當然就是空的囉~
那我要怎麼拿回以前的信件?
6. 首先, 先在OutlookExpress的本機資料夾按右鍵, 選擇新增資料夾, 資料夾的名稱看你個人的喜好, 方便您辨識, 這裡舉例就叫做”2008″好了.
7. 新增 “2008” 資料夾後, 因為裡面是空的, 在剛剛的目錄底下不會幫你產生 “2008.dbx”, 所以我們隨便將”收件匣”裡面的一封信複製到”2008″資料夾裡面. 在檢查看看, 目錄底下出現了新的 “2008.dbx” 了! 酷吧~
8. 現在我們再把Outlook Express關掉.
9. 到
C:\Documents and Settings\Administrator\Local Settings\Application Data\Identities\{1936D57C-EA58-4C14-9A09-D10B5B2BFCF5}\Microsoft\Outlook Express
10. 我們現在要騙系統說2008.dbx就是我們之前命名的”收件匣1.dbx”, 所以就把”2008.dbx”先刪掉, 再把”收件匣1.dbx”命名成 “2008.dbx”.
11. 打開OutlookExpress, 你就會發現”2008″資料夾裡面多了很多信囉~這些信就是你之前2G爆掉的信啦~ 但值得提醒的是, Outlook Express 的資料夾極限大小是2G,所已表示這個2008資料夾很難在塞入更多的郵件, 建議您還是把它儘量分類出去, 保持在2G以下.
維持良好的刪信, 信件分類的習慣才是最好的解決方法喔 ^_^
希望可以幫助到大家.