2015年4月25日 星期六

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還簡單多了~~根本一瞬間就解決了嘛!!


2015年4月18日 星期六

WPF學習筆記 - 0 什麼是WPF?

之前在台灣一直是從事ASP.NET 寫web的工作,沒想到到日本後,原以為要開始寫JAVA WEB,但事事難料…竟然先被抓去寫WPF…雖然工作三年多一直都是走M$派系的,不過還真沒用過WPF…頂多只知道它跟Silverlight差不多…

到底什麼是WPF?

WPF,全名Windows Presentation Foundation,是從.net 3.0所增加的新功能,簡單來說比較廣為人知的Silverlight其實只算是WPF的一小部份,專門用在WEB方面要跟FLASH抗衡的(沒想到一個HTML5就把大家都打趴了…)

然而WPF可沒這麼容易被打趴,本來被指派到這個任務真的興趣缺缺…(痛恨學習古老的技術…),不過仔細研究了…兩天(幹麻這樣,人家才剛學嘛),發現其實WPF還算是滿有發展性的,從Windows vista之後,到現在的8.1,幾乎M$的APP很多都使用WPF開發的,就連地表上最強的開發工具VS也是哦~~

平常要寫Windows的app,大家第一個想到的可能是windows form,不過winform在畫面上要客制化非常的困難,而且背後全都是靠C#來執行的(連畫面都是),寫過WEB MVC的應該非常的痛恨VIEW和LOGIC綁在一起才對…因此WPF就是一個能解決這個問題的好東西!!

WPF採用MVVM的架構,也就是VIEW、MODEL、VIEW-MODEL的作法,與MVC有點類似,詳細就請大家自己google,code-behind可以選擇用c#或vb,view的部份則是使用一種類似XML的語法,XAML(eXtensible Application Markup Language),就像是WEB的HTML一樣,相信入門不是很困難,也因此,使用WPF不被微軟的框架所限制住,更容易可以客制化畫面,做出精美的效果,當然使用Visual studio還是可以達到像寫winform那樣拖拉產生畫面的效果,另外微軟還有提供Expression Blend,可以讓設計師更容易做出美美的介面~~(在UI/UX受到重視的年代,這可是很重要的)

因為小艾我也才讀了一天的資料而已,並沒有很熟悉,不過中文的資料真的不多,就算有也是簡體的,而且許多書籍是2006~8年還是.net 3.0的時候出的,現在已經到4.5了,實在是有些不同…如果想看中文的書籍,小艾目前找到一本《WPF編程寶典》有.net 4.5配vs2012的版本,書講的還挺詳細的,雖然我也才剛讀,不過還是推薦一下,因外這個網站《WPF tutorial》,雖然是英文的,不過講的淺顯易懂,也推薦給大家

接下來會慢慢的打上一些學習WPF的文章,當做是自己的備忘囉~~

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

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