Các điều khiển nâng cao trong WPF – Advanced UI controls in WPF

advanced

Không dừng lại ở việc  cung cấp những điều khiển UI  như ComboBox, ListBox, TextBox,…, với những chức năng cơ bản và đặc tính text đơn điệu như trong Windows Form, WPF còn cho phép người  lập trình tùy biến thuộc tính của những điều khiển trên để biến chúng thành những điều khiển UI  phức hợp,  với nhiều đặc tính giao diện phong phú, tinh tế, kết hợp text, hình ảnh,… Để đạt được hiệu quả tương tự, với những công nghệ trước đây như MFC, cần tiêu tốn nhiều công sức lập trình. Qua các ví dụ cụ thể trong bài giảng này, chúng ta sẽ thấy WPF tạo ra chúng đơn giản như thế nào.

1. Hộp lựa chọn Font chữ (Font Chooser)

–  Mục tiêu của phần này là tạo lập một điều khiển dạng ComboBox, trong đó, liệt kê danh sách các phông chữ hệ thống. Tên của mỗi phông chữ lại được hiển thị dưới dạng chính phông chữ đó. Điều này cho phép người dùng xem trước định dạng phông chữ trước khi chọn chúng. Bạn  có thể đã quen thuộc với dạng Combox này khi sử dụng các ứng dụng của Microsoft Office như Word, Excel, PowerPoint,…

–    Dưới đây đây là mã XAML để tạo control này:

<Window x:Class="Demo_Font_chooser.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Demo Font Chooser - ThanhCuong.wordpress.com" Height="350" Width="525">
    
        <!--Sử dụng stack panel theo chiều dọc làm layout chính của form-->
        <StackPanel Width="300" Orientation="Vertical" Height="150" VerticalAlignment="Top">
            <!--Khai báo tạo lập tiêu đề của điều khiển-->
            <TextBlock  FontFamily="Times New Roman" FontWeight="Bold" FontSize="20"> 
                Fonts System:
            </TextBlock>
            <!--Khai báo tạo điều khiển Combox-->
            <ComboBox  ItemsSource="{x:Static Fonts.SystemFontFamilies}" SelectedIndex="3">
                <!--Khai báo định nghĩa thuộc tính dữ liệu gắn với mỗi mục chọn-->
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" FontFamily="{Binding}"/>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </StackPanel>
    
</Window>

–  Trong phần khai báo tạo điều khiển ComboBox, ta khai báo nguồn dữ liệu được dùng cho các mục trong hộp danh sách thông qua thuộc tính  ItemsSource. Bằng việc gán  ItemsSource=”{x:Static Fonts.SystemFontFamilies}”  ta định nghĩa nguồn dữ liệu này là danh sách các phông chữ hiện có của hệ thống máy  tính hiện thời. Thuộc tính SelectedIndex cho phép định ra chỉ số của chỉ mục ngầm định được chọn ban đầu trong danh sách phông, cụ thể trong trường hợp này là phông chữ đầu tiên (SelectedIndex=”3″).  Trong phần khai báo định nghĩa thuộc tính dữ liệu của mỗi chỉ mục trong ComboBox  (phần  tử <ComboBox.ItemTemplate>), ta lồng vào một điều khiển TextBlock, trong đó, nội dung hiển thị là phông chữ tương ứng (Text=”{Binding}”) và dạng phông hiển thị nội dung cũng chính là phông chữ tương ứng với chỉ mục này (FontFamily=”{Binding}”).

image

–  Như vậy chỉ cần vài dòng lệnh XAML đơn giản chúng ta đã  tạo được một control rất hữu dụng.

–  Click vào đây để download về project demo Font Chooser viết trên Visual Studio 2010

 

2.  Hộp danh mục ảnh (Image ListBox)

–  Trong phần này, ta xây dựng một hộp danh mục (ListBox) các đồ uống có kèm theo ảnh. Rõ ràng tính trực quan của giao diện người dùng sẽ tăng hơn nhiều so với một danh sách dạng text đơn điệu. 

2.1  Thêm dữ liệu ảnh vào tài nguyên của project

Trước hết, ta thêm các ảnh đồ uống cần thiết vào tài nguyên của project theo các bước sau:
–  Ở cửa sổ Solution Explorer, ta nhắp chuột phải vào tên project –> Xuất hiện bảng chọn chức năng.
–  Chọn mục Add…>Existing Item –> Xuất hiện cửa sổ cho phép lựa chọn file.
–  Trong hộp danh sách Files of type, ta chọn Image Files –> Các file ảnh trong thư mục hiện thời sẽ xuất hiện.
–  Tìm đến các file ảnh cần hiển thị trong danh sách và chọn OK.
–  Kết quả, trong cửa sổ Solution Explorer, ta thấy xuất hiện các file ảnh tương ứng.

2.1 Source code chương trình

–  Giả thiết rằng các file ảnh đã được nạp vào project, sau đây là mã XAML của chương trình:

<Window x:Class="Demo_Image_ListBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Demo Image ListBox - ThanhCuong.wordpress.com" Height="322" Width="349">
    <Grid>
        <!--Khai báo tạo lập một hộp danh mục với các thuộc tính về căn lề, chiều rộng,…-->
        <ListBox Margin="10,10,0,13" Width="280" Name="ListImage" HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch">
            <!--Khai báo tạo lập một chỉ mục con trong hộp danh mục với thuộc tính màu nền-->
            <ListBoxItem Background="Beige">
                <!--Lồng vào chỉ mục này một StackPanel để có thể chứa nhiều hơn 1 phần tử UI con theo chiều ngang-->
                <StackPanel Orientation="Horizontal">
                    <!--Khai báo tạo lập một ảnh đồ uống ở đầu mỗi chỉ mục-->
                    <Image Width="50" Height="50" Source="image\c++ language.jpg"></Image>
                    <!--Khai báo tạo lập một dòng chữ chỉ tên đồ uống-->
                    <TextBlock Margin="5" VerticalAlignment="Center" FontFamily="Times New Roman" 
                                FontStyle="Italic" FontSize="18">C++ Language</TextBlock>
                </StackPanel>
            </ListBoxItem>

            <!--Khai báo chỉ mục 2 tương tự như trên-->
            <ListBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Width="50" Height="50" Source="image\algorithm.jpg"></Image>
                    <TextBlock Margin="5" VerticalAlignment="Center" FontFamily="Times New Roman" 
                                FontStyle="Italic" FontSize="18">Algorithms</TextBlock>
                </StackPanel>
            </ListBoxItem>

            <!--Khai báo chỉ mục 3 tương tự như trên-->
            <ListBoxItem Background="Beige">
                <StackPanel Orientation="Horizontal">
                    <Image Width="50" Height="50" Source="image\dare.jpg"></Image>
                    <TextBlock Margin="5" VerticalAlignment="Center" FontFamily="Times New Roman" 
                                FontStyle="Italic" FontSize="18">Dare to Dream</TextBlock>
                </StackPanel>
            </ListBoxItem>

            <!--Khai báo chỉ mục 4 tương tự như trên-->
            <ListBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Width="50" Height="50" Source="image\cost.jpg"></Image>
                    <TextBlock Margin="5" VerticalAlignment="Center" FontFamily="Times New Roman" 
                                FontStyle="Italic" FontSize="18">Money</TextBlock>
                </StackPanel>
            </ListBoxItem>

            <!--Khai báo chỉ mục 5 tương tự như trên-->
            <ListBoxItem Background="Beige">
                <StackPanel Orientation="Horizontal">
                    <Image Width="50" Height="50" Source="image\complicacy.jpg"></Image>
                    <TextBlock Margin="5" VerticalAlignment="Center" FontFamily="Times New Roman" 
                               FontStyle="Italic" FontSize="18">Complicacy</TextBlock>
                </StackPanel>
            </ListBoxItem>
        </ListBox>
    </Grid>
</Window>

– Giờ thì nhấn F5 để xem kết quả nào;

image

–  Như vậy, điểm mấu chốt để bổ sung thêm các thuộc tính giao diện như ảnh, text, checkbox,…, vào mỗi chỉ mục của hộp danh sách chính là việc kết hợp các phần tử UI riêng lẻ tương ứng vào cùng một phần tử Panel nằm trong khai báo chỉ mục. Trong trường hợp này, với mỗi khai báo chỉ mục <ListBoxItem> ta thêm vào một  <StackPanel Orientation=”Horizontal”> theo chiều ngang, trong đó, chứa một phần tử <Image> và 1 phần tử <TextBlock> . Nguồn dữ liệu ảnh được xác định qua thuộc tính Source=”<tên ảnh đã được bổ sung vào project>”.

–  Click vào đây để download project demo Image ListBox viết trên Visual Studio 2010

3. Hộp mở rộng (Expander)

–  Hộp mở rộng Expander là một trong những điều khiển UI (User Interface) mới được giới thiệu trong WPF như một điều khiển cơ bản. Expander cho phép thu gọn hoặc mở rộng một nội dung nào đó chứa trong nó, giống như một node trong TreeView, bằng việc click vào biểu  tượng mũi  tên (hướng  lên, nếu điều khiển đang ở  trạng  thái mở  rộng; hướng xuống, nếu đang ở  trạng  thái  thu gọn). Điều khiển này rất tiện lợi: Khi diện tích form chính quá chật hẹp vì nhiều chức năng được trình bày trên cùng giao diện, ta có thể sử dụng Expander để chứa một số chức năng ít dùng có thể tạm thời được ẩn dưới một tên nhóm chung.

–  Trong ví dụ sau đây, ta sẽ làm một menu chứa 2 mục là đồ uống và đồ ăn, mỗi mục sẽ chứa danh sách các sản phẩm tương ứng mà nhà hàng cung cấp. Ta sử dụng Expander để có thể mở rộng/thu gọn từng mục nêu trên. Sau đây là mã XAML của ứng dụng:

<Window x:Class="Demo_Expander.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Demo Expender - thanhcuong1990.info" Height="300" Width="250">

    <!--Sử dụng stackpanel làm layout chính-->
    <StackPanel>
        <!--Khai báo tạo lập Expander chứa danh mục đồ uống-->
        <Expander FontFamily="Times New Roman" FontSize="14" FontStyle="Oblique" 
                Header="Drink" Background="#acbf43" >
            <!---Khai báo ListBox  chứa danh mục đồ uống-->
            <ListBox >
                <!--Khai báo các chỉ mục con trong danh mục đồ uống-->
                <!--Mỗi mục con được trang trí bằng một biểu tượng đi kèm text-->
                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="programmer.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Sinh tố Carot</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="provsnoobzk5.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Nước cam vắt</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="scannx7jy6.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Trà sữa</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="thuagiayvevoi.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Sữa chua đá</TextBlock>
                    </StackPanel>
                </ListBoxItem>
            </ListBox>
        </Expander>

        <!--Khai báo Expander chứa danh mục đồ ăn-->
        <Expander FontFamily="Times New Roman" FontSize="14" FontStyle="Oblique" 
                    Header="Foods" Background="DarkOrange">
            <ListBox>
                <!--Khai báo các chỉ mục con trong danh mục đồ ăn-->
                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="thumb_25083303.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Nem Bình Định</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Tien hoa 1.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Phở Hà Nội</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Tien hoa 2.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Hủ tiếu mì</TextBlock>
                    </StackPanel>
                </ListBoxItem>

                <ListBoxItem>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="Tien hoa 3.jpg" Height="20"></Image>
                        <TextBlock VerticalAlignment="Center">Bún bỏ Huế</TextBlock>
                    </StackPanel>
                </ListBoxItem>
            </ListBox>
        </Expander>
    </StackPanel>
</Window> 

– F5 –> Resultimage

 

–  Như ta thấy việc sử dụng Expander trong WPF rất đơn giản, với cùng nguyên tắc như các điều khiển UI cơ bản khác. Ở đây ta sử dụng 2 hộp mở rộng Expander: một chứa danh mục đồ uống được đặt trong một ListBox; một chứa danh mục đồ ăn trong một ListBox.

–  Click vào đây để download project Demo Expander viết trên Visual Studio 2010

4.  Hộp soạn văn bản đa năng (RichTextBox)

–  Hộp  soạn văn bản đa năng RichTextBox là một  trong những điều khiển  có chức năng phong phú. Không chỉ cho phép soạn sửa và hiển thị các nội dung text đơn thuần, RichTextBox còn cho phép thay đổi phông chữ  (Verdana, Times  New  Roman,…), kiểu  chữ  (nghiêng,  đậm, gạch  chân),…  Đặc  biệt,  điều  khiển RichTextBox trong WPF/.NET 4.0 còn cho phép kiểm tra/gợi ý sửa đổi lỗi chính tả tiếng Anh của nội dung văn bản chứa trong đó. RichTextBox trong WPF/.NET 4.0 là phần tử được cải tiến về cơ bản so với phiên
bản trước của điều khiển RichTextBox trong .NET 2.0. Tuy nhiên, cùng với  sự mở  rộng về  chức năng là việc bổ sung các API mới cũng như những cách thức sử dụng khác.  

4.1 Chức năng cơ bản

–   Để thêm mới một hộp soạn thảo đa năng vào form, ta dùng mã XAML như sau:

<RichTextBox x:Name="XAMLRichBox" SpellCheck.IsEnabled="True"  
                MinHeight="100"></RichTextBox>

–  Thuộc tính x:Name là từ khoá xác định danh tính của RichTextBox được tạo.

–  Thuộc tính này đóng vai trò là tham chiếu cho phép ta sau này buộc mã lệnh C# vào điều khiển. Thuộc tính MinHeight xác định số dòng có thể thấy được của hộp soạn thảo, giá trị này ngầm định bằng 1.

–  Thuộc tính SpellCheck.IsEnabled=”True” kích hoạt tính năng kiểm tra lỗi chính tả tiếng Anh trong nội dung văn bản và gợi ý những từ đúng có thể để thay thế, giống như Microsoft Word. Tuy nhiên, nếu chỉ với một RichTextBox, ta không có cách nào để sửa đổi định dạng của văn bản trong RichTextBox như đánh chữ nghiêng, chữ đậm, đổi phông chữ, vân vân. Muốn đạt được điều này, ta phải buộc mã lệnh vào giao diện Command của RichTextBox.

4.2 Giao diện Command

–  Microsoft chủ  trương để người phát  triển  làm việc với RichTextBox thông qua giao diện Command. Mặc dù khái niệm này không mới đối với phần lớn người phát triển giao diện đồ hoạ người dùng, việc cài đặt và cú pháp trong XAML có chút khác biệt.

–  Ta cần  thêm một  ToolBar  và  một  số  nút  bấm  hai  trạng  thái  (ToggleButton)  để  gắn  lệnh  điều  khiển RichTextBox đã  tạo. Thuộc  tính Command  trên mỗi điểu khiển kể  trên sẽ xác định chức năng mà  ta muốn kích hoạt trên RichTextBox,. Trong khi đó, thuộc tính CommandTarget xác định RichTextBox nào ta muốn chức năng kích hoạt của các nút bấm nhằm vào. Sau đây là đoạn mã XAML bổ sung thêm một ToolBar và 3 nút bấm hai trạng thái:

–  Dưới đây là đoạn code demo viết bằng XAML:

<Window x:Class="Demo_RichTextBox.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> <!--Sử dụng StackPanel làm layout chính--> <StackPanel Orientation="Vertical"> <!--Khai báo toolbar--> <ToolBar> <!--Nút tô đậm--> <ToggleButton MinWidth="40" Command="EditingCommands.ToggleBold" CommandTarget="{Binding ElementName=XAMLRichBox}" TextBlock.FontWeight="Bold">B </ToggleButton> <!--Nút in nghiêng--> <ToggleButton MinWidth="40" Command="EditingCommands.ToggleItalic" CommandTarget="{Binding ElementName=XAMLRichBox}" TextBlock.FontStyle="Italic">I </ToggleButton> <!--Nút gạch chân--> <ToggleButton MinWidth="40" Command="EditingCommands.ToggleUnderline" CommandTarget="{Binding ElementName=XAMLRichBox}"> <TextBlock TextDecorations="Underline">U</TextBlock> </ToggleButton> </ToolBar>

<!--Khai báo tạo lập RichTextBox--> <RichTextBox x:Name="XAMLRichBox" SpellCheck.IsEnabled="False" MinHeight="100" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="275"> </RichTextBox> </StackPanel> </Grid> </Window>

– Và kết quả của đoạn chương trình trên là:

image

–  Click vào đây để download project Demo RichTextBox được viết trên Visual Studio 2010

-> Như vậy qua bài viết này bạn có thể nắm được cách kết hợp các control lại với nhau sẽ tạo nên những control mới rất hữu ích. Đây cũng được coi là những sáng tạo nhỏ trong lập trình giao diện. Bạn cũng có thể tự sáng tạo ra nhưng giao diện cho riêng mình. Chúc bạn thành công!

(Tham khảo MSDN)

Advertisements

About thanhcuong1990

Handsome and talent!! ^^
This entry was posted in WPF. Bookmark the permalink.

One Response to Các điều khiển nâng cao trong WPF – Advanced UI controls in WPF

  1. Lê Quang says:

    Mình làm như thế này hoài không ra:

    Trong khi đó: SelectedItemStation = ListStations[0];
    Đã xác định được thằng hiển thị đầu tiên! Thiệt tình chả hiểu sao nữa cả!
    Và đã kiếm được từ bạn!

    “Thuộc tính SelectedIndex cho phép định ra chỉ số của chỉ mục ngầm định được chọn ban đầu trong danh sách phông, cụ thể trong trường hợp này là phông chữ đầu tiên (SelectedIndex=”3″)”

    Thank verry much!
    Thân!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s