2008年3月31日星期一

C# - Worth To Use Extension Methods

對於經常在VisualBasic和C#之間往來的我來說,會明白到C# Strong Type的好處,但同時亦覺得VB語法寬鬆的好處.
因為在C#中要經常做轉型(Convert.ToString / .ToString etc) , 在VB中,Object可以和Integer相加 , 在C#的話, 就肯定是出現Error.

這一陣子寫Silverlight的時間,經常有很多object type出現,由於是coordinate,所以必須轉換成Double.

就以下面的Code為例,ImgBall的GetValue是object type,不能就這樣做operation,所以必須用Convert.ToDouble轉型,但單單一小節Code,已經出現3次:
if (Convert.ToDouble(ImgBall.GetValue(Canvas.LeftProperty)) < Convert.ToDouble(ImgPaddle.GetValue(Canvas.LeftProperty)) + 5)
{
ImgBall.SetValue(Canvas.LeftProperty, Convert.ToDouble(ImgPaddle.GetValue(Canvas.LeftProperty)) + 5);
}

Extension Methods的出現可大大降低程式碼的長度,效能雖然沒有得益,但增加程式碼的可讀性.
以下我就示範一下如何透過Extension Methods令整個程序更美觀.

建立一個Class檔案 (ext.cs) ,在Namespace低下加入:
public static class ext
{
/// <summary>
///  Get Dependency Object and Convert to Double.
/// </summary>
public static Double GetDouble(this Image img, DependencyProperty property)
{
return Convert.ToDouble(img.GetValue(property));
}

/// <summary>
///  Get Canvas.LeftProperty From Image.
/// </summary>
public static Double GetCanvasLeft(this Image image)
{
return GetDouble(image, Canvas.LeftProperty);
}
/// <summary>
///  Get Canvas.TopProperty From Image.
/// </summary>
public static Double GetCanvasTop(this Image image)
{
return GetDouble(image, Canvas.TopProperty);
}
}

以上程序就是把Property引入,並進行類型轉換,要注意緊記加入"static"的Modifier.

回到開始的部份,我們已經可以在Image Member中找到GetCanvasLeft 和GetCanvasTop,直接引用就已經可以得到Double類型的數值了,是不是簡短很多呢~
if (ImgBall.GetCanvasLeft()  < ImgPaddle.GetCanvasLeft() + 5)
{
ImgBall.SetValue(Canvas.LeftProperty, ImgPaddle.GetCanvasLeft() + 5);
}

其實某程度上Extension Methods和傳統的Function相似,都是可以引入Parameter , return數值等等, 但Extension Methods是指定在某一個類別下衍生出功能,當實際使用時就會依據類別而出現於Member List中,亦算是符合一般程式概念.

WordPress 2.5 Release!!!!

呢次2.5版本是大更新,由v2.3x直接跳過v2.4出v2.5已可見.

主要新加:
Dashboard Widgets (太好了,Login後,唔洗再睇到無用既資訊)
Multi-file upload with progress bar (呢個都唔錯喇,等左咁耐終於有既Function)
Few-click plugin upgrades (呢個我覺得有所保留,因為好睇Plug-in本身,好似SEO All-In-One,我見過好多人用One Click Update而失敗)
Friendlier visual post editor (轉用TinyMCE 3.0 ,但不知功能是不是又係大幅減化)
Built-in galleries (效果還可以,不過NextGen(即係我用緊呢個)更好,Demo按此: WordPress 2.5 Build-in Gallery

還有很多細微更新,可以去官網睇睇:
http://wordpress.org/development/2008/03/wordpress-25-brecker/


2008年3月29日星期六

Adobe Photoshop Express

我試用過幾下,與同類型既Webware比較,我覺得FotoFlexerPicnik比較好用,不過自己對畫圖冇任何興趣,所以都沒有太試真。

Adobe Photoshop Express :
http://www.photoshop.com/express/

2008年3月20日星期四

原來而家RSS Reader已經咁先進

自從果時用過Bloglines幾個星期後,都冇再用類似既o野,
琴日Check我Blog既Stats,發現好多人都用Google Reader,我又試下用,覺得幾好用。

起碼介面簡潔,好過Bloglines。但係我就驚見Google Reader有一樣好神奇既功能,就係當標題拉到最尾一個時,佢會自動下載其後的標題。

我一直以為RSS的文章數目是限制於XML File。
例如我用Sinablog果時,Sina最多只可以Feed 10個文章,就算你set多過10個,就唔會出現第11個文章。
所以就唔明白Google Reader點樣做到拎之後的文章,有冇網友可以簡單講解一下?

2008年3月18日星期二

Silverlight vs. Flash




Silverlight vs. Flash: The Developer Story
http://weblogs.asp.net/jezell/archive/2007/05/03/silverlight-vs-flash-the-developer-story.aspx

Silverlight vs. Flash – An Analysis Report
http://silverlight.net/forums/p/3015/8462.aspx

Silverlight - Animations Programmatically With C#/VB

既然SL 2.0支援.NET Language,除了用StoryBoard之外,當然還可以如WPF / Xbap般,使用程式去做動畫喇。
以下是其中一個例子,由10x10的正方形漸變大小至600x400:
public void Create_And_Run_Animation()
{
//新建一個10x10和紅色的正方形
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 10;
myRectangle.Height = 10;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;

//把正方形加進既LayoutRoot的子集
LayoutRoot.Children.Add(myRectangle);

//Duration設成8秒,時間越短越快,你可以想像成Timeline一樣
Duration duration = new Duration(TimeSpan.FromSeconds(0.8));

//因為我們需要同時改變寬和高,所以要建立兩個DoubleAnimation
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();

myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;

//新增StoryBoard
Storyboard sb = new Storyboard();
sb.Duration = duration;

sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);

//把目標轉向myRectangle和Property
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
Storyboard.SetTargetProperty(myDoubleAnimation1, "(Rectangle.Width)");
Storyboard.SetTargetProperty(myDoubleAnimation2, "(Rectangle.Height)");

myDoubleAnimation1.To = 600;
myDoubleAnimation2.To = 400;

//放進Resouce,就好似使用Blend建立的StoryBoard 時一樣
LayoutRoot.Resources.Add(sb);

//開始動畫
sb.Begin();
}

Silverlight - Using StoryBoard From Expression Blend

很多年前都一直有玩Flash,約是Flash 4至Flash MX2004期間。所以Blend其實不是太難上手,玩過Silverlight 2.0 和Expression Blend後,我學習SL覺得首先的就是要放下Flash的基本概念。雖然Flash和Blend都同樣使用Timeline,Keyframe去達到動畫效果,但Blend並沒有類似MovieClip的東西出現,反之是用一樣叫StoryBoard的東西,透過改變Target,Property去做到一個"劇本"的效用。而StoryBoard同樣是XAML,並不是好像MovieClip般可以當是一個物件。

以下是我學習期間,導入StoryBoard方法

按此觀看Demo

Page.xmal
<Canvas>
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<DoubleAnimation x:Name="myDoubleAnimation" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:2" AutoReverse="True" />
</Storyboard>
</Canvas.Resources>
<Rectangle x:Name="MyAnimatedRectangle1" Canvas.Top="10" Canvas.Left="10" Width="100" Height="100" Fill="Blue" MouseLeftButtonDown="Start_Animation" />
<Rectangle x:Name="MyAnimatedRectangle2" Canvas.Top="10" Canvas.Left="120" Width="100" Height="100" Fill="Blue" MouseLeftButtonDown="Start_Animation" />
<Rectangle x:Name="MyAnimatedRectangle3" Canvas.Top="10" Canvas.Left="230" Width="100" Height="100" Fill="Blue" MouseLeftButtonDown="Start_Animation" />
<Rectangle x:Name="MyAnimatedRectangle4" Canvas.Top="10" Canvas.Left="340" Width="100" Height="100" Fill="Blue" MouseLeftButtonDown="Start_Animation" />
</Canvas>

Page.xaml.cs
public void Start_Animation(object sender, MouseEventArgs e)
{
myStoryboard.Stop();
Rectangle myRect = (Rectangle)sender;
myDoubleAnimation.SetValue(Storyboard.TargetNameProperty, myRect.Name);
myStoryboard.Begin();
}

以上例子就是利用sender的Name去代入SetValue()中的myRect.Name,
換句話說,透過SetValue()再引用正確的dependency property,就可以同樣Override 其他數值。

LINQPad - Free LinQ Query Builder

Well, you don't have to!  LINQPad lets you interactively query databases in a modern query language: LINQ.  Kiss goodbye to SQL Management Studio!

LINQPad supports everything in C# 4.0 and Framework 4.0:

  • LINQ to Objects
  • LINQ to SQL, Entity Framework and DevForce Models
  • LINQ to XML
  • Parallel LINQ

And that's not all - there's also specific support for:

LINQPad is also a great way to learn LINQ: it comes loaded with 500 examples from the book, C# 4.0 in a Nutshell. There's no better way to experience the coolness of LINQ and functional programming.

And LINQPad is more than a LINQ tool: it's an ergonomic C#/VB/F# scratchpad that instantly executes any expression, statement block or program with rich output formatting – the ultimate in dynamic development. Put an end to those hundreds of Visual Studio Console projects cluttering your source folder!

Download LINQPad :
http://www.linqpad.net/

Adding Timer to Silverlight Application

前一段時間學習LINQ,算是了解基本的概念和應用後,就試一試了解Silverlight。

一開始就想寫一個類似以前任天堂時代的撞撞波遊戲,遊戲的中"板板"已經完成跟隨Mouse,"波波"亦可以照預設方面進行Double Animation , 但是Game Logic和Game Loop部份真是很難搞。



例如波波反彈的方向,總不是一直都是直線前進,直線反彈吧。

力度,速度等等都是考慮的,本身我未讀過Vector Maths和Geometry方面的東西。
幸好網上有人已經用Silverlight 1.0 + JavaScript寫了一個Sample,我可以作為參考。
但Game Loop部份,Silverlight 1.0可以使用setTimeout()的方法。但Silverlight 2.0本身既沒有setTimeout(),
亦沒有什麼Timer Control的東西。所以查了一查後,我們可以用DispatcherTimer去做到。

詳情可以按連結去查看:
For Silverlight 1.1:
http://adoguy.com/2007/05/15/Silverlight_and_Timers.aspx

For Silverlight 2.0:
http://pagebrooks.com/archive/2008/03/07/silverlight-2-has-a-timer-dispatchertimer.aspx

2008年3月14日星期五

LINQ 學習筆記 - LINQ to SQL

記得當時ADO.NET出現其中的一個目的,就是要提供一個Layer可以Offline作業,事實上利用DataSet, DataTable般的In-memory資料集合,的確對Server和程式本身有不少的好處。

LINQ to SQL是LinQ架構下重要的子集,在LINQ Providers中,可以大致分為 :
  1. LINQ to Objects
  2. LINQ to XML
  3. LINQ to SQL
  4. LINQ to DataSets
透過LINQ to SQL,我們可以把整個資料庫轉換成Data Model,當中包含Table的結構,DataType等等。而Data Field本身亦會隨Table成為Member角色,而產生的DataContext亦充當了一個Gateway,例如以往我們使用SQL Command時,發生Command String錯誤,有時會是Remote Side 回存的SQL Exception,但使用LINQ to SQL後,在Design Time時,已經可能知道錯誤,這大大加強資料庫的可程式性。

現在我就示範如何去把Database轉成LINQ 上使用的Data Class。

我使用了SQL 2005的AdventureWorks Sample Database ,在Visual Studio中的Database Explorer加入資料連接 ,Right Click Project => Add New Item ,再選 [ LINQ to SQL Class ] ,之後就會新增一個dbml檔案。

我選用了Contact / Product / Customer / SalesOrderHeader / SalesOrderDetail 五個Table, 在Database Explorer 選取後,把它們Drag & Drop至中間的位置後,Visual Studio 便會自動建立Class至dbml檔案。

greenshot_2008-03-13_16-11-59.pnggreenshot_2008-03-13_16-29-21.png

新增一個Form , 隨意加入一個DataGridView和兩個ComboBox後,建立一個BuildGrid的程序,輸入Code之後,已經可以做到基本的DataBinding了。(如下圖)

greenshot_2008-03-13_16-32-26.png greenshot_2008-03-13_16-35-23.png

嚴格來說,只需要三行的程式碼就可以 :
DataClass.infodata1_DataContext dc = new LINQPlayer.DataClass.infodata1_DataContext();
var select = (from c in dc.Contact where c.ContactID != null select new { c.ContactID , c.NameStyle, Name = (c.Title + ' ' + c.FirstName + ' ' + c.MiddleName + ' ' + c.LastName), c.EmailAddress, c.Phone, c.ModifiedDate }).Take(Convert.ToInt32(cboTake.SelectedItem)).Skip(Convert.ToInt32(cboSkip.SelectedItem));
dgv1.DataSource = select;


不用如ADO.NET般建立SQL Connection ,因為在剛才建立的dbml檔案,內裡已經有Connection String,同時亦免除SQL Command, SQLDataReader 等等,因為當中的var select是Anonymous types , 具有直接存放Data Collection的能力。透過LinQ的Query Syntax,你可以使用屬於extension method,如[skip] , [take] 去做有條件性選擇。

greenshot_2008-03-13_16-49-10.png

作者 : 達Ming
最後更新 : 13-3-2008

原創文章 - 轉貼時請註明出處 : http://tatmingstudio.blogspot.com/2008/03/linq-linq-to-sql.html
(有錯請留言更正,多多指教)

2008年3月13日星期四

LINQ 學習筆記 - Data Class / Data Context

DataClass是可以自行編寫的,但我相信非必要都不會那樣做,因為一個Database動輒有二三十個Table,Column不計其數,要自己編寫的話,真是要花很多時間,而且Visual Studio中又有提供Data Model的Generator。不過學習 LINQ之前,我們都看看DataClass是怎樣做Mapping。

greenshot_2008-03-13_14-07-31.png

我使用了簡單的NorthWind Access DB ,為"Customers"的Table 建立一個Class檔案:
class DCClass
{
// 取得Customers的Table , 進行Table Mapping
[Table(Name = "Customers")]
public class CustomerDC
{
// Column : CustomerID
[Column(IsPrimaryKey = true)]
public string CustomerID { get; set; }
// Column : Name 並轉成 ContactName
[Column(Name = "ContactName")]
public string Name { get; set; }
// Column : City
[Column]
public string City { get; set; }
}
}


在程式中,我就可以使用這個Class了,以Button為例 :
private void button2_Click(object sender, EventArgs e)
{
//建立IDbConnection
IDbConnection MyConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Nwind.mdb;User Id=admin;Password=;");
//建立dc為新的DataContext
DataContext dc = new DataContext(MyConnection);
//建立EntityType的Customers 並取得DCClass中的CustomerDC結構
Table<dcclass.customerdc> Customers = dc.GetTable<dcclass.customerdc>();
//可以直接使用LinQ語法去做Query了
DataGridView1.DataSource = from c in Customers where c.CustomerID.StartsWith("A") select new { MyCustomerID = c.CustomerID, MyCustomerName = c.Name, MyCity = c.City };
}


以上就是基本的DataClass , DataContext , LinQ的示範,但試想下,假如你的Database有廿多個Table,每個Table就有十多個Column的話,可以想像編寫DataClass是十分花時間的。 下一次,我就會示範如何使用LinQ to SQL Designer快速地建立Data Class。

作者 : 達Ming
最後更新 : 13-3-2008

原創文章 - 轉貼時請註明出處 : http://tatmingstudio.blogspot.com/2008/03/linq-data-class-data-context.html
(有錯請留言更正,多多指教)

2008年3月4日星期二

至今我用過最好的免費Free Burning Software

之前用CDBurnerXP,其實使用上都沒有大問題,不過軟件就總是長江後浪推前浪.有更好的,我就會轉用.
Ashampoo Burning Studio Free 名符其實是Nero Burning replacement ,因為Ashampoo 同樣做到Audio和Video DVD.

官方網站:
http://www.ashampoo.com/en/usd/pin/0710/Offline/Ashampoo-Burning-Studio-6

Download:
http://www.download.com/Ashampoo-Burning-Studio-Free/3000-2646_4-10776287.html

The Ashampoo Burning Studio 6 FREE keeps all the advantages of its predecessor and adds multi-disc file backup, an integrated audio CD ripper and further improved support for the exciting new Blu-ray format with capacities of up to 25 gigabytes per layer.

Many users are tired of over-complicated CD burning applications that are getting harder and harder to use. Sometimes you can waste most of your time just trying to find a function. Ashampoo Burning Studio 6 FREE focuses on what you want: To burn discs quickly, easily, with maximum quality and minimum hassle. It includes everything you need to be able to do that. And it excludes everything that could get in the way.