2015年4月26日 星期日

WPF學習筆記 - 8 WPF ToolTip

可以在任何的Controls中使用,當鼠標移到控制項上就會出現提示訊息

ToolTip="你想提示的話"

比較特別的是,ToolTip不只可以放string type,而是可以放object type,
所以你可以在ToolTip做出豐富的效果

<Button>
                <Button.Content>
                    <Image Source="/WpfTutorialSamples;component/Images/folder.png" Width="16" Height="16" />
                </Button.Content>
                <Button.ToolTip>
                    <StackPanel>
                        <TextBlock FontWeight="Bold" FontSize="14" Margin="0,0,0,5">Open file</TextBlock>
                        <TextBlock>
                        Search your computer or local network
                        <LineBreak />
                        for a file and open it for editing.
                        </TextBlock>
                        <Border BorderBrush="Silver" BorderThickness="0,1,0,0" Margin="0,8" />
                        <WrapPanel>
                            <Image Source="/WpfTutorialSamples;component/Images/help.png" Margin="0,0,5,0" />
                            <TextBlock FontStyle="Italic">Press F1 for more help</TextBlock>
                        </WrapPanel>
                    </StackPanel>
                </Button.ToolTip>
</Button>

ToolTip就像root control一樣,可以讓我們在裡面加上許多的controls

其他屬性

ToolTipService.ShowDuration="5000" - 提示出現5秒
ToolTipService.ShowOnDisabled ="True" - 被disable的control也會出現提示


text render
TextOptions. TextFormattingMode
TextOptions. TextRenderingMode

從.NET 4.0之後,developer可以自行指定想要用怎樣的模式來顯示text,使用TextOptions

2015年4月25日 星期六

WPF學習筆記 - 7 WPF 控制項 - CheckBox、RadioButton

CheckBox - 繼承自ContentControl,可客制化

<StackPanel Margin="10">
                <Label FontWeight="Bold">Application Options</Label>
                <CheckBox>Enable feature ABC</CheckBox>
                <CheckBox IsChecked="True">Enable feature XYZ</CheckBox>
                <CheckBox>Enable feature WWW</CheckBox>
</StackPanel>

// IsChecked="True" - 表示被選取

較複雜的CheckBox,可在CheckBox裡放進TextBlock和Image

<CheckBox IsChecked="True">
                        <WrapPanel>
                                <TextBlock>
                                        Enable feature <Run FontWeight="Bold">XYZ</Run>
                                </TextBlock>
                                <Image Source="/WpfTutorialSamples;component/Images/question.png" Width="16" Height="16" Margin="5,0" />
                        </WrapPanel>
</CheckBox>

一個CheckBox通常以ture或false代表它是否被選取,不過可以加上IsThreeState="True",來表視第三種狀態,Ture, False, Null
可以用在一組CheckBox,來表示全選,全不選,只有幾個被選…

最後可以配合Checked, Unchecked,來改變被選取的狀態



 RadioButton - 繼承自ContentControl,可客制化

<Label FontWeight="Bold">Are you ready?</Label>
<RadioButton GroupName="ready">Yes</RadioButton>
<RadioButton GroupName="ready">No</RadioButton>
<RadioButton GroupName="ready" IsChecked="True">Maybe</RadioButton>

<Label FontWeight="Bold">Male or female?</Label>
<RadioButton GroupName="sex">Male</RadioButton>
<RadioButton GroupName="sex">Female</RadioButton>
<RadioButton GroupName="sex" IsChecked="True">Not sure</RadioButton>

設計出兩組Radio,以GroupName分組,如不需要分組,可以去掉GroupName,就是六個RadioButton為同一組

客制化RadioButton

<RadioButton Margin="0,5">
                        <WrapPanel>
                                <Image Source="/WpfTutorialSamples;component/Images/cancel.png" Width="16" Height="16" Margin="0,0,5,0" />
                                <TextBlock Text="No" Foreground="Red" />
                        </WrapPanel>
</RadioButton>

作法與CheckBox相同

WPF學習筆記 - 6 WPF 控制項 - Label

<Label Content="This is a Label control." />

Label和TextBlock的差別

1. Lable底下可以放任何東西,TextBlock只能放文字
2. Label會自動幫你在Top和Left加上padding,TextBlock需要自行設定
3. Label可以用access keys

<StackPanel Margin="10">
                <Label Content="_Name:" Target="{Binding ElementName=txtName}" />
                <TextBox Name="txtName" />
                <Label Content="_Mail:" Target="{Binding ElementName=txtMail}" />
                <TextBox Name="txtMail" />
</StackPanel>

此時只要按下Alt+N,forcus就會被換到txtName上

在Label裡同時使用AccessText和Image

<Label Target="{Binding ElementName=txtName}">
            <StackPanel Orientation="Horizontal">
                <Image Source="http://cdn1.iconfinder.com/data/icons/fatcow/16/bullet_green.png" />
                <AccessText Text="_Name:" />
            </StackPanel>
        </Label>
<TextBox Name="txtName" />

快捷鍵的功能仍然可以使用!


WPF學習筆記 - 5 WPF 控制項 - TextBox、PasswordBox

用過winform應該都知道TextBox就是供使用者輸入的文字區塊

<TextBox /> - 單行

<TextBox AcceptsReturn="True" TextWrapping="Wrap" />
AcceptsReturn讓TextBox變多行,
TextWrapping="Wrap"當TextBox的字過長時,會自動把原本輸入的字往上移,讓使用者輸入新的字

其他屬性
SpellCheck.IsEnabled="True" Language="en-US" - 開啟自動拼字檢查功能
IsReadOnly="True" - TextBox只能唯讀

綁定SelectionChanged事件

<DockPanel Margin="10">
                <TextBox SelectionChanged="TextBox_SelectionChanged" DockPanel.Dock="Top" />
                <TextBox Name="txtStatus" AcceptsReturn="True" TextWrapping="Wrap" IsReadOnly="True" />
</DockPanel>

private void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
                        TextBox textBox = sender as TextBox;
                        txtStatus.Text = "Selection starts at character #" + textBox.SelectionStart + Environment.NewLine;
                        txtStatus.Text += "Selection is " + textBox.SelectionLength + " character(s) long" + Environment.NewLine;
                        txtStatus.Text += "Selected text: '" + textBox.SelectedText + "'";
}

// textBox.SelectionStart - 判斷鼠標在哪個字元,從0開始
// Environment.NewLine - 斷行
// textBox.SelectionLength - User選了幾個字元

// textBox.SelectedText - User選了什麼字

PasswordBox - 供使用者輸入密碼的區塊

TextBox的內容改為隱藏
<PasswordBox />

可以更改成想要的字
<PasswordBox PasswordChar="X" />

設定最大長度
<PasswordBox MaxLength="6" />

用C#獲得PasswordBox的密碼

IntPtr p = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(txtPassword.SecurePassword);
string password = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p);

2015年4月23日 星期四

WPF學習筆記 - 4 WPF 控制項 - TextBlock

TextBlock光看名字就知道,就是一個讓你顯示文字的區塊

<TextBlock>This is a TextBlock</TextBlock>

如果字串過長,字會自動被隱藏

<TextBlock Margin="10" Foreground="Red">
    This is a TextBlock control<LineBreak />
    with multiple lines of text.
</TextBlock>

<TextBlock Margin="10" TextTrimming="CharacterEllipsis" Foreground="Green">
    This is a TextBlock control with text that may not be rendered completely, which will be indicated with an ellipsis.
</TextBlock>

<TextBlock Margin="10" TextWrapping="Wrap" Foreground="Blue">
    This is a TextBlock control with automatically wrapped text, using the TextWrapping property.
</TextBlock>

<LineBreak /> : 直接規定這裡要換行,不是很好的作法,較無彈性。
TextTrimming="CharacterEllipsis" : 超過的字會以...代替,如果使用WordEllipsis,會以單字為單位,就不會有一個字突然被切斷的情形發生。
TextWrapping="Wrap" : 視位置自動換行,一定會顯示出所有的字出來。

其他功能:
<Bold></Bold> - 粗體
<Italic></Italic> - 斜體
<Underline></Underline> - 下底線
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate" NavigateUri="https://www.google.com">link</Hyperlink> - 超連結

Backend會多一個Hyperlink_RequestNavigate() method,需要實作它

private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
        System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}

<span></span> - 作用與HTML的span有點相像,可以設定許多的屬性,以便管理

<TextBlock Margin="10" TextWrapping="Wrap">
   This <Span FontWeight="Bold">is</Span> a
   <Span Background="Silver" Foreground="Maroon">TextBlock</Span>
   with <Span TextDecorations="Underline">several</Span>
   <Span FontStyle="Italic">Span</Span> elements,
   <Span Foreground="Blue">
       using a <Bold>variety</Bold> of <Italic>styles</Italic>
   </Span>.
</TextBlock>

用C#設格式

public partial class TextBlockCodeBehindSample : Window
{
    public TextBlockCodeBehindSample()
    {
        InitializeComponent();
        TextBlock tb = new TextBlock();
        tb.TextWrapping = TextWrapping.Wrap;
        tb.Margin = new Thickness(10);
        tb.Inlines.Add("An example on ");
        tb.Inlines.Add(new Run("the TextBlock control ") { FontWeight = FontWeights.Bold });
        tb.Inlines.Add("using ");
        tb.Inlines.Add(new Run("inline ") { FontStyle = FontStyles.Italic });
        tb.Inlines.Add(new Run("text formatting ") { Foreground = Brushes.Blue });
        tb.Inlines.Add("from ");
        tb.Inlines.Add(new Run("Code-Behind") { TextDecorations = TextDecorations.Underline });
        tb.Inlines.Add(".");
        this.Content = tb;
    }
}

WPF學習筆記 - 3 WPF Resources

靜態的Resources

<Window x:Class="WpfTutorialSamples.WPF_Application.ResourceSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="ResourceSample" Height="150" Width="350">
    <Window.Resources>
        <sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
    </Window.Resources>
    <StackPanel Margin="10">
        <TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" />
        <TextBlock>Just another "<TextBlock Text="{StaticResource strHelloWorld}" />" example, but with resources!</TextBlock>
    </StackPanel>
</Window>

在 <Window.Resources>裡設定了一個靜態的resource,在後面的TextBox就可以直接使用{StaticResource strHelloWorld}來呼叫

其他的Resource types

<Window.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>

        <x:Array x:Key="ComboBoxItems" Type="sys:String">
            <sys:String>Item #1</sys:String>
            <sys:String>Item #2</sys:String>
            <sys:String>Item #3</sys:String>
        </x:Array>

        <LinearGradientBrush x:Key="WindowBackgroundBrush">
            <GradientStop Offset="0" Color="Silver"/>
            <GradientStop Offset="1" Color="Gray"/>
        </LinearGradientBrush>
</Window.Resources>

<StackPanel Margin="10">
        <Label Content="{StaticResource ComboBoxTitle}" />
        <ComboBox ItemsSource="{StaticResource ComboBoxItems}" />
</StackPanel>

上面可以看到除了普通的string格式外,還有Array可以用,用在ComboBox、下拉式選擇…做為初始值非常適合

區域Resource

<StackPanel Margin="10">
    <StackPanel.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </StackPanel.Resources>
    <Label Content="{StaticResource ComboBoxTitle}" />
</StackPanel>

這種寫法離開StackPanel後,這個Resources就不能用囉,就像區域變數一樣

如果像這樣寫在App.xaml裡,整個app都可以使用

<Application x:Class="WpfTutorialSamples.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             StartupUri="WPF application/ExtendedResourceSample.xaml">
    <Application.Resources>
        <sys:String x:Key="ComboBoxTitle">Items:</sys:String>
    </Application.Resources>
</Application>

不只在xaml裡可以呼叫resources,也可以從backend呼叫
// .FindResource("keyname")
lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());
lbResult.Items.Add(this.FindResource("strWindow").ToString());
lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());

簡單的就可以從xmal和cs去呼叫到resources囉~~

2015年4月21日 星期二

WPF學習筆記 - 2 WPF Application設定說明

上一章我們完成了一個最簡單的WPF程式,現在要說明一下裡面的細節

先看一下MainWindow.xaml

<Window x:Class="WpfApplication1.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>
       
    </Grid>
</Window>

Title - 可設定視窗的標題
x:Class - 用來告訴xaml要使用哪個class

你會發現在MainWindow.xaml.cs裡有個MainWindow class,

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

在這裡你可以發現MainWindow是個partial class,因為它和MainWindow.xaml是一組的,在runtime時會把兩個部份結合在一起,產生出window出來

其他重要的屬性:Icon, ResizeMode, ShowInTaskbar, SizeToContent, Topmost, WindowStarupLocation, WindowState

接下來看另一個自動產生的檔案App.xaml

<Application x:Class="WpfApplication1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
       
    </Application.Resources>
</Application>

這裡記錄著當你的application剛被啟動時的一些資訊。

StartupUri - 初始的頁面

與App.xaml對應的App.xaml.cs

public partial class App : Application
{
}

在這裡可以設定application剛被開始的一點參數

如果我們將App.xaml中的StartupUri="MainWindow.xaml" 更改為 Startup="Application_Startup"

並修改App.xaml.cs為

private void Application_Startup(object sender, StartupEventArgs e)
{
            // Create the startup window
            MainWindow wnd = new MainWindow();

            // Do stuff here, e.g. to the window
            wnd.Title = "Hello, WPF!!";

            // Show the window
            wnd.Show();
}

也可以從backend產生出新視窗,並且title為Hello, WPF!!

2015年4月20日 星期一

WPF學習筆記 - 1 Hello,WPF!!

今天要介紹一下WPF的基本架構,在VS裡新建一個WPF Application後,會看到VS自動幫我們加了幾個檔案MainWindow.xmal、App.xaml、App.config

這裡要先帶大家看一下最重要的MainWindow.xmal

<Window x:Class="WpfApplication1.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>
        // 新增一個TextBlock,填入Hello, WPF!
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                Hello, WPF!
        </TextBlock>
    </Grid>
</Window>

第一個WPF程式就這樣完成囉~~(啥米…也太快了吧!!)
以上所看到的程式碼就是XAML,與HTML非常的相像,都是一個起始tag,配上一個結束的tag組成,例如
<Button></Button>
or
<Button/>
or
<Button>我是按鈕<Button>
用法非常簡單,也可以加上額外的屬性
<Button>
    <Button.FontWeight>粗體字</Button.FontWeight>
    <Button.Content>內容</Button.Content>
</Button>
比較重要的觀念是,XAML裡其實只能放一個物件,就像是HTML都是
<html>
  <head></head>
  <body>
      網頁內容
  </body>
</html>
而在XAML裡就是以<Window></Window>為主tag,而裡頭只能放一個tag,所以通常會放<Grid></Grid>之類的…超級TAG,因為在Grid裡頭還可以放許多的tag,所以把Grid想成跟body一樣比較容易記囉~~當然超級TAG不只有Grid,後續會陸續介紹其他的
除了直接編寫XAML外,使用c#也可以動態控制XAML

Button btn = new Button();
btn.FontWeight = FontWeights.Bold;

WrapPanel pnl = new WrapPanel();

TextBlock txt = new TextBlock();
txt.Text = "Multi";
txt.Foreground = Brushes.Blue;
pnl.Children.Add(txt);

txt = new TextBlock();
txt.Text = "Color";
txt.Foreground = Brushes.Red;
pnl.Children.Add(txt);

txt = new TextBlock();
txt.Text = "Button";
pnl.Children.Add(txt);

btn.Content = pnl;
pnlMain.Children.Add(btn);

這一段程式碼就等於以下的XAML

<Button FontWeight="Bold">
    <WrapPanel>
        <TextBlock Foreground="Blue">Multi</TextBlock>
        <TextBlock Foreground="Red">Color</TextBlock>
        <TextBlock>Button</TextBlock>
    </WrapPanel>
</Button>

Hello, WPF是不是比Hello, World還簡單多了~~根本一瞬間就解決了嘛!!


[泰國] 芭達雅大城八日遊 Day7、8 - 瑪哈泰寺、Wat Ratchaburana、帕蒙空博碧寺、帕席桑碧寺、Hua Ro market、Chantharakasem National Museum、Amporn Department Store

第七天行程,早上吃飯店早餐,算不錯吃,只是有螞蟻,但吃完沒拉,所以應該還好 吃飽後飽嘟嘟車,一小時 200 泰銖,比自己叫還便宜,終於要來世界遺產之旅了 第一站:瑪哈泰寺,應該是大城最有名的景點了,入門票大人 120 ,小孩免費,其實不便宜 大城指標性景點...