Application=Code+Markup 讀書筆記 1-4

bjq_ren發表於2008-08-11
1

       沒有WPF新東西,略過。

2

1Background是一個Brush物件,而不是Color物件:

            this.Background = new SolidColorBrush(Colors.Black);

而不可以:

            this.Background = Colors.Black;

2Brush相關的類,都位於System.Windows.Media中:

結構:

Brush(抽象類)

       GradientBrush(抽象類)

              LinearGradientBrush

              RadialGradientBrush

       SolidColorBrush

       TileBrush(抽象類)

              DrawingBrush

              ImageBrush

              VisualBrush

3Freezable

因為Brush繼承自Freezable類,實現了Chenged事件,brush只要一有改變,就會觸發該事件,客戶區就會被重繪。

以下語句

            brush = Brushes.Black;

也能產生

            brush = new SolidColorBrush(Colors.Black);

的效果。唯一的區別,前者是利用Brushes類的靜態只讀屬性取得的SolidColorBrush物件,處於“凍結”狀態,不能再被改動——這種“凍結”機制派生於Freezable類,大大提高了效率。

那麼,以下語句的搭配就會執行期報錯:

            brush = Brushes.Black;

            Color clr = Color.FromRgb(1, 2, 3);

            Brush.Color = clr;

為了解決這個問題,我們要製造一個沒有凍結的複製版本,取代第一條語句:

            brush = Brushes.Black.Clone();

其實,這一句,才和new SolidColorBrush(Colors.Black);是等效的。

此外,從SystemColors返回的系統級筆刷物件也都是凍結的。

4)漸變筆刷之:LinearGradientBrush

預設Point座標使用相對座標:左上角(0, 0),右下角(1, 1),其間所有Point的座標都小於1

也可以指定Point使用決定座標定位,這是一個MappingMode列舉值。我們可以這樣設定Brush筆刷物件的這個屬性:

            brush.MappingMode = BrushMappingMode.Absolute;   //預設值為RelativeToBoundingBox

LinearGradientBrush的最簡單形式,四個引數,兩個Color和兩個Point,表現為建構函式:

new LinearGradientBrush(Colors.Red, Colors.Black, new Point(0, 0), new Point(1, 1)

Colors.Red引數對應new Point(0, 0)引數,

Colors.Black引數對應new Point(1, 1)引數,

此外,也可以取代Point,而使用angle:以360度為一週。

GradientSpreadMethod列舉:

            brush.SpreadMethod = GradientSpreadMethod.Pad;

負責填充剩餘的區域,有三個值(假設由RedBlue漸變):

Pad,預設值,剩餘區域延續之前的顏色。

Reflect,剩餘區域繼續漸變,沒有突變,為此要逆轉。

Repeat,剩餘區域繼續漸變,有突變。與上面的區別我會把圖補上。

LinearGradientBrush僅有的兩個屬性:StartPointEndPoint從而確定brush的範圍。


GradientStops
屬性

GradientStops,為漸變新增更多的顏色,而不僅侷限於開始和結束兩種,這是一個GradientStopCollection集合,其中的元素是GradientStop

            GradientStopCollection gsList = new GradientStopCollection();
            gsList.Add(
new GradientStop(Colors.Red, 0.01));
            gsList.Add(
new GradientStop(Colors.Black, 0.02));

            brush.GradientStops 
= gsList;

GradientStops的建構函式:new GradientStop(Colors, Offset)

這裡Offset表示在StartPointEndPoint的方向長度為L的地方。L的計算公式:

L = (EndPoint - StartPoint) * Offset

5)漸變筆刷之:RadialGradientBrush

RadialGradientBrush類似於LinearGradientBrush

沒有StartPointEndPoint。

3個屬性CenterRadiusXRadiusY,預設值都是0.5

有一個GradientOrigin屬性,作為漸變發生的原點,預設值都是(0.5, 0.5)

6)傳統.NET中的三種Timer,其中只有System.Windows.Forms中的TimerTick事件是發生在同一個當前主執行緒中(其他兩個TimerSystem.ThreadingSystem.Timers中,它們的Tick事件都發生在不同的執行緒中)。

WPF中,要使用System.Windows. Threading中的DispatcherTimer,才能在主執行緒中控制Freeable物件——因為Freeable建立於主執行緒。

7)總結,Window中有四個屬性是Bursh型別的:

BackgroundForeground以及OpacityMaskBorderBrush

3 內容

1ContentWindow最重要的屬性,決定在視窗中顯示什麼東西,Object型別,即可以放置型別物件,當然Window中不能放置Window,因為Window必須是根元素。

2Content屬性中的Object分為兩類:字串,派生於UIElement的視覺化元素。

WPF中,UIElement很重要,用來實現鍵盤、滑鼠等事件的處理,它有一個OnRender方法。

派生於UIElement的類,重寫OnRender方法,可以自定義新的繪圖:

    public class SimpleEllipse : FrameworkElement
    
{
        
protected override void OnRender(DrawingContext drawingContext)
        
{
            drawingContext.DrawEllipse(Brushes.Red, 
new Pen(Brushes.Black, 24), new Point(00), 1010);
        }

    }

於是可以直接使用這個SimpleEllipse,並作為Content顯示:

            SimpleEllipse elip = new SimpleEllipse();

            Content = elip;

3FrameworkElement是直接派生於UIElement的唯一類。而WPF中所有的元素都派生於FrameworkElement,這樣UIElement就做到了最大化的抽象,如果以後有了新的框架,如WPF2,我們可以另建派生於UIElement的類FrameworkElement2,然後重新派生新的元素。

4)不要混淆ContentElementContentControl

ContentControl是控制元件,具有Content屬性。

ContentElement只是其他控制元件的一部分。


4 按鈕及其他控制元件

1Command命令

基於一個單一點來路由控制元件的訊息,為此在ButtonBase類和MenuItem類中定義了Command屬性。我們可以將ButtonCommand屬性設定為以下5個類的靜態屬性:

ApplicationCommandsComponentCommandsMediaCommandsNavigationCommand——以上4個類屬於System.Windows.Input

EditingCommands——屬於System.Windows.Document

這些類的靜態屬性都為RoutedUICommand型別,後面將會演示如何自定義一個RoutedUICommand型別。

使用如下:

            button1.Command = ApplicationCommands.Paste;

            CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, PasteOnExecute, PasteCanExecute));

對應的兩個事件處理器如下:

        void PasteOnExecute(Object sender, ExecutedRoutedEventArgs e)
        
{
            Title 
= Clipboard.GetText();
        }


        
void PasteCanExecute(Object sender, CanExecuteRoutedEventArgs e)
        
{
            e.CanExecute 
= Clipboard.ContainsText();
        }

一定要在PasteCanExecute中判斷是否支援當前按鈕是否有效,比如說當前剪下板中有一幅圖片,則PasteCanExecute會將e.CanExecute設定為false,按鈕就會立刻被禁用(disabled)

這樣,這個ApplicationCommands.Paste可以在很多地方使用,只是在不同地方,指定的處理方法不同

我們可以指定按鈕的文字設定為該命令的標準文字,如下顯示“貼上”或“Paste”:

            button1.Content = ApplicationCommands.Paste.Text;

2ToggleButton

ToggleButton不是抽象類,可以用來代替它的子類RadioButtonCheckBox控制元件。它也有IsChecked屬性,表現為按鈕凸出還是凹陷兩種樣式,注意到這是一個可空型別,所以獲取到它的值後要進行強制型別轉換:

(bool)btn.IsChecked

對於派生於此的RadioButtonCheckBox控制元件,它們的IsChecked屬性也是要這樣處理。空值,即“是”與“不是”的第三種選擇:“取消選擇”,在XAML中表現為

<ToggleButton Name="r"IsChecked="{x:Null}" >

C#中,即:

       r.IsChecked = null;

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15123181/viewspace-422937/,如需轉載,請註明出處,否則將追究法律責任。

相關文章