2010年7月29日 星期四

WPF 學習:EventRouting

這次學到的是 WPF 的 EventRouting

有一個 Window,xaml 如下

<Window x:Class="WpfApplication1.MainForm"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainForm" Height="300" Width="300" >
    <Grid>
        <StackPanel Name="MyPanel"></StackPanel>
    </Grid>
</Window>

而 code 如下。

public MainForm()
{
    InitializeComponent();

    for (int i = 0; i < 5; i++)
    {
        var button = new Button() {Content = "Button " + i};
        MyPanel.Children.Add(button);
        button.Click += new RoutedEventHandler(button_Click);
    }
}

void button_Click(object sender, RoutedEventArgs e)
{
    var button = sender as Button;
    MessageBox.Show(button.Content.ToString());
}

執行時,會產生5個 button。每一個 button 被Click 後,會拋出所click 的按鍵訊息。

這樣的寫作方式與以前的 windows form 並沒有什麼兩樣。每個 button 的 click event 都註冊了相同的 event handler,似乎有點笨。

Event Bubbling

由於 event bubbling 的關係,button 的也會傳到其 Parent Container,在這個例子是名為 MyPanel 的 StackPanel。因此理論上MyPanel 可以收的到 Click Event.

問題來了,StackPanel 並沒有 Click Event,因此無法註冊 EventHandler. 如下圖。

image

RountEvent

雖然 MyPanel 無法直接註冊 Click Event, 但在 WPF 中由於 DependecyProperty 的幫助,我們可以使用 MyPanel.AddHandler方法的協助來註冊 Button 的 Click Event 的 Event Handler

public MainForm()
{
    InitializeComponent();

    for (int i = 0; i < 5; i++)
    {
        var button = new Button() {Content = "Button " + i};
        MyPanel.Children.Add(button);
        //button.Click += new RoutedEventHandler(button_Click);
    }
    MyPanel.AddHandler(Button.ClickEvent, new RoutedEventHandler(button_Click));            
}

void button_Click(object sender, RoutedEventArgs e)
{
    var button = e.Source as Button; //我也改了這一行
    MessageBox.Show(button.Content.ToString());
}
注意到我改了 e.Source。e.Source 是指真正發生 Event 的物件,即 Button。而sender 會指到 MyPanel,並不是我們想要的。

2010 年 TPC-E Benchmark,微軟 SQL Server 全面勝出??

繼上次 2007 的 SQL Server 2005 vs Oracle 效能評比,這次我隔了三年才再看 TPC 的資料。

這次多了 TPC-E 的測試標準。在 TPC-E 的測試標準下,無論是效能(Top Ten TPC-E Results by Performance)或是效能/價格(Top Ten TPC-E Results by Price/Performance),微軟的 SQL Server 大獲全勝,包辦了前十名。

image

image

而舊版的 TPC-C 測試標準,Top Ten TPC-C Results by Performance: 則完全看不到微軟 SQL Server 的身影,而Top Ten TPC-C Results by Price/Performance:的效能/價格,則 SQL Server 才勉強地擠到第三名。

image

image

TPC-E 與 TPC-C 到底差在哪裡啊!怎麼兩者會差這麼多。當然 TPC 網站有對兩者的解釋。英文說明太長(TPC-C, TPC-E) 。

實在看不懂。查一下 Google,看到了 新伺服器效能評測標準TPC-E出爐這一篇。原來 TPC-E 模擬目前複雜的交易環境,十足的 B2B。而舊版 TPC-C 則只單純地模擬一家零售銷售商店經理向倉庫下達訂單,模擬系統的交易效能。

簡單地說,以現在的網路交易環境,TPC-E 比較準啦!微軟可樂壞了吧!

那Oracle 與  DB2 呢?看來這兩個資料庫不喜 TPC-E 的 Benchmark,尚未提出任何測試報告呢。

參考

TPC-E和TPC-C测试结果比较之我见

新伺服器效能評測標準TPC-E出爐

昔日贵族TPC-C今成"鸡肋" TPC-E欲篡位

Microsoft Still the Only Database Vendor Posting TPC-E Scores

WPF 學習:Binding

WPF 除了 Declaration Programming 外,還有一個最強的功能就屬於 Binding 了。

假設現在有個需求,有一個 Button 與 TextBox。TextBox 所輸入的文字必須即時地設定為 Button 的 Text。

Window Form

如果以 WinForm 來實作的話,就必須以 Event Handler 的方式來處理。程式碼如下.

private void textBox1_TextChanged(object sender, EventArgs e)
{
    button1.Text = textBox1.Text;
}
好處是相當簡易清楚。但想一想,程式中充滿了這類的 Event Handler 也是相當雜亂的事。

WPF

WPF 則是使用 Binding 的技術來克服這樣的需求,不必一項項的以 Event Handler 來實作。

<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
  <Button    Content="{Binding ElementName=HelloTextBox, Path=Text}" Height="100" Margin="0,12,0,198" />
  <Button    Height="100" Margin="0,128,0,83" >
    <Button.Content>
    <Binding ElementName="HelloTextBox" Path="Text" />
    </Button.Content>
  </Button>
  <TextBox Text="Hello" Name="HelloTextBox" Margin="0,234,374,49" />
</Grid>
</Window>

第一個 Button ,其 Content 說明了其資料來源的Element 為 HelloTextBox,讀取路徑(Path)為Text。

第二個 Button 則使用了另一種相等的寫法,更清楚但語法稍嫌太長。

結論

這兩種WPF 的方法使用了 Binding(繫結),簡單地以宣告的方式取代了 Event Handling。更棒的是,這類的 Binding 可以使用到非常多的屬性,如Style, Icon 等。

2010年7月22日 星期四

LINQ to Entities: 可使用的 CLR Functions

我們知道 LINQ to Entities 很好用。但並非所有的 c# 習慣都可以寫到 LINQ to Entities 的 expression 中。

例如:下面的語法就會出錯。

var q = from i in ctx.MyObjects
        where i.GuidField == Guid.Parse("xxxx-xxxx-xxxxxxx-xxxx")
        select i;

解決的方法呢,就是將 Guid.Parse(”xxxx-xxx”) 這一樣拿出去 LINQ 外即可。如下

var guid = Guid.Parse("xxxx-xxxx-xxxxxxx-xxxx");
var q = from i in ctx.MyObjects
        where i.GuidField == guid
        select i;

LINQ to Entities 看到了語法中有不支援的 CLR Function,就不知道該怎麼辦。

那LINQ to Entities支擾哪些 CLR Fuction呢?見 CLR Method to Canonical Function Mapping

LINQ to Entity: 出現 Only parameterless constructors and initializers are supported in LINQ to Entities 錯誤

問題

使用 LINQ to Entities 時,出現了如下的錯誤。

Only parameterless constructors and initializers are supported in LINQ to Entities

原因

原來,我使用了 ReSharper 的 Convert Anonymous Type to Named Type 的功能,它會建立一個新的 Type,並沒有預設建構子。程式寫起來如下

from u in _entities.UserInfoes
select new UserViewModel(u.Displayname, u.UserId, u.Email

而 Entity Framework 竟然不支援這樣的寫法?真怪。

解法

解法呢?就把UserViewModel改成有預設建構子。呼叫方式如下

from u in _entities.UserInfoes
select new UserViewModel
{
    Displayname = u.Displayname,
    UserId = u.UserId,
    Email = u.Email
}

2010年7月18日 星期日

對 .NET Framweork 進行除錯

有時候,我們程式寫著寫著效能不佳,就可能怪起微軟的 .NET Framework了。微軟看來也怕了這一點,趕緊公佈 .NET Framework 的 Source Code,並且還可以在 Visual Studio 2010 進行除錯。

以下就介紹如何設定。

步驟1:下載

請到 http://referencesource.microsoft.com/netframework.aspx , 下載 .NET 4 的 Source Code 及 Symbol.

image

步驟2:安裝

下載回來的是 Net_4.msi。安裝時設定指定路徑為個人檔案的路徑,如 C:\Users\yourname\Documents\RefSrc,我就用了這一個路徑。

步驟3:設定

設定的步驟比較多。打開 Visual Studio 2010,執行功能表Tools/Options,選擇 General 頁。
不要勾選 "Enable Just My Code (Managed only)"。
勾選 "Enable .NET Framework source stepping"。
勾選 "Enable source server support"。
不要勾選"Require source files to exactly match the original version"


如下圖:

image

再選到 Symbols 路徑

按新增目錄,輸入 C:\Users\yourname\Documents\RefSrc\symbols
在 Cache symbols in this directory 中輸入 C:\Users\yourname\Documents\RefSrc\symbols\SymbolCache

完成後按確定。
image

大功告成。之後您就可以使用 F11來除錯了。

微軟公開的 Source Code

微軟已經儘量的公開 Source Code 了。大部份是與協力廠商。換句話說,是要簽保密協定的。

而一些比較沒有商業機密的,如 .net framework,早就公開了。見 Available Source Code Components

Share with Facebook