Thiết kế giao diện bằng xaml

1 / Giới thiệu về giao diện trong wpf

Nói đến thiết kế giao diện kể cả trong lập trình web , winform chúng ta thường sử dụng các khái niệm như Layout , Control .Các công nghệ lập trình khác nhau có tên gọi khác nhau nhưng ý nghĩa đều tương tự như thế

Layout là bộ khung chứa cấu trúc giao diện ứng dụng

Control là các điều khiển : nút bấm ( button) , lựa chọn ( CheckBox ) .Các Control được đặt trên layout .Các bạn có thể xem minh họa bằng hình dưới đây :

Winform dùng C# ( vb.net ) để định nghĩa giao diện , trong WPF chúng ta dùng Xaml để định nghĩa giao diện .Tất nhiên khi lập trình runtime trong WPF chúng ta cũng có thể dùng C# để định nghĩa giao diện

Trên môi trường Visual Studio cũng hỗ trợ việc kéo thả các Control và sinh mã tự động .Tuy nhiên lời khuyên khi học lập trình xaml là nên code bằng ta vì nó rất đơn giản và cho ta cái nhình thật sự về cấu trúc giao diện

2/ Tạo Project WPF dùng Visual studio

Để thực hành các ví dụ , trước tiên ta dùng Visual Studio tạo 1 Project WPF như sau :

  • Khởi động VS chọn File/New Project : alt

  • Chọn các thông số như : phiên bản .net , tên Project , tên solution , nơi lưu Project như hình sau: alt

  • Nhấn OK ta được giao diện Project do VS sinh mã như sau : alt

  • VS tạo sẵn File MainWindow.xaml .Window này sẽ được chọn khởi động đầu tiên khi chạy ứng dụng .Việc khai báo Window khởi động được định nghĩa trong file App.xaml hoặc App.cs ( App.cs thực ra là file code behind của file App.xaml)

  • Mã file App.xaml như sau :

<Application x:Class="SampleWpf.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>
  • Mã MainWindow.xaml như sau :
<Window x:Class="SampleWpf.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>
  • Giao diện Design cho xem trước giao diện , hoặc kéo thả Control như winform như sau :

alt

  • Giao diện kéo thả :

alt

Mặc dù wpf cũng hỗ trợ kéo thả các control rồi tự động sinh mã xaml .Tuy nhiên chúng tôi khuyên bạn nên tự code mã xaml để hiểu bản chất cũng như xây dựng các giao diện chuyên nghiệp bởi xaml rất đơn giản .

Việc code giao diện xaml cũng tương tự và có phần dễ hơn cả code html trong lập trình web

Chú ý : Trong winform , mỗi giao diện được gọi là Form , trong wpf các giao diện được gọi là Window hoặc là View ( trong mô hình MVVM)

  • Mã C# ( Code behind )

alt

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SampleWpf
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
  • Chạy thử ứng dụng bằng nhấn Start trên thanh công cụ như hình sau : alt
  • Ta được kết quả như hình sau : alt

3/ Ví dụ Control dùng xaml trong wpf

  • Tạo mới 1 Window đặt tên là Sample1.xaml bằng cách chuột phải Project như hình sau :

alt

  • Chọn các thông số như hình sau : alt

  • Mã Sample1.xaml như sau :

<Window x:Class="SampleWpf.Sample2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Sample2" Height="300" Width="300">
    <Grid>
    </Grid>
</Window>
  • Code lại mã Sample1.xaml như sau :
<Window x:Class="SampleWpf.Sample1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Sample1" Height="300" Width="300">
    <StackPanel>
        <Button Content="Button1" />
    </StackPanel>
</Window>

Button được khai báo

<Button Content="Button1"/>

// trong cấu trúc trên thì Button là tên loại Control Content là Attribute (Thuộc tính) .Attibute Content dùng hiển thị nội dung button .Có rất nhiều Attribute tương ứng với các Control .Đôi khi các Control lại có chung các Attribute .Điều này ta có thể khai báo chung bằng các file Style trong wpf

Hiện tại ta chỉ quan tâm tới các thuộc tính cơ bản định nghĩa giao diện .Các thuộc tính tương tác với CSDL sẽ được giới thiệu tại các bài học về CSDL .

  • Để chạy Sample1.xaml đầu tiên , ta đổi mã trong file App.xaml như sau :
<Application x:Class="SampleWpf.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="Sample1.xaml">
    <Application.Resources>
    </Application.Resources>
</Application>
  • Chạy ứng dụng được như hình sau : alt

Ta thấy Window Sample1.xaml được gọi , và button đã được hiển thị trên Window sample1

Hiện tại nhấn nhấn vào nút bấm button thì chưa có gì do ta chưa viết sự kiện cho nút bấm .Chúng ta chủ yêu đang học cách xây dựng giao diện ứng dụng bằng xaml

4/ Layout Control :

Ở ví dụ trên (3) ta đã đặt Control trong layout StackPanel .Thực ra StackPanel cũng là 1 Control , nhưng ta hiểu chúng là các control Layout để phân biệt với các layout thường như : button, textBox …

Ta tạm hiểu layout là cách bố cục chương trình trên 1 nền nào đó gọi là layout.

Việc bố trí layout trong wpf rất mềm dẻo phù hợp với nhiều kích cỡ hay độ phân giải màn hình.

a/ StackPanel

StackPanel bố trí các Control theo thứ tự trước sau ( như đối với cách bố trí thẻ của html )

Mặc định các phần tử được bố trí theo chiều dọc ( từ trên xuống dưới ) .

Có thể thay đổi chỉ định khai báo bố trí theo chiều ngang : Orientation="Horizontal"

  • Ví dụ : Để tiện trong việc quản lý các ví dụ , chúng ta tạo thư mục LayoutView trong Project để lưu các Window về layout bằng cách chuột phải Project chọn như hình sau :

alt

Đặt tên thư mục là : LayoutView

Thêm mới 1 Window đặt tên là StackPanelView.xaml trong thư mục LayoutView

  • Ta code mã StackPanelView.xaml như hình sau :
<Window x:Class="SampleWpf.LayoutView.StackPanelView"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="StackPanelView" Height="300" Width="300">
    <StackPanel>
        <Button Content="Button1" />
        <TextBlock Text="Hello world" />
    </StackPanel>
</Window>
  • Khai báo chạy StackPanelView.xaml trong file App.xaml như sau :
<Application x:Class="SampleWpf.App"           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="/LayoutView/StackPanelView.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>
  • Chạy ứng dụng được kết quả như hình sau : alt

  • Nếu muốn sắp xếp các control theo chiều ngang thì khai báo mã StackPanelView.xaml như sau:

<StackPanel Orientation="Horizontal">
        <Button Content="Button1" />
        <TextBlock Text="Hello world" />
    </StackPanel>
  • Chạy lại ứng dụng được kết quả như hình sau : alt

  • Nếu muốn sắp xếp các control theo chiều ngang thì khai báo mã StackPanelView.xaml như sau:

<StackPanel Orientation="Horizontal">
        <Button Content="Button1" />
        <TextBlock Text="Hello world" />
</StackPanel>
  • Chạy lại ứng dụng được kết quả như hình sau :

alt

b/ WrapPanel

WrapPanel cho phép sắp các phần tử từ trái sang phải sang trái.Khi hết sẽ tự động xuống hàng

Khác với StackPanel sắp theo chiều ngang là các Control sẽ bố trí theo hàng ngang nhưng chỉ 1 hàng ( sẽ tự động co dãn độ rộng để hiển thị )

Ta tạo mới Window : WrapPanelView trong thư mục LayoutView

  • Code WrapPanelView như sau
<Window x:Class="SampleWpf.LayoutView.WrapPanelView"       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="WrapPanelView"
        Height="300"
        Width="300">
    <WrapPanel>
        <Button Content="Button1" />
        <TextBlock Text="Hello world" />
        <Button Content="Button2" />
        <Button Content="Button3" />
        <Button Content="Button4" />
        <Button Content="Button5" />
        <Button Content="Button6" />
    </WrapPanel>
</Window>
  • Khai báo khởi động WrapPanelView trong App.xaml như sau :
<Application x:Class="SampleWpf.App"            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="/LayoutView/WrapPanelView.xaml">
    <Application.Resources>

    </Application.Resources>
</Application>
  • Chạy ứng dụng được kết quả như hình sau : alt

c/ DockPanel

DockPanel cho phép các phần tử bám vào các cạnh của Control .

Cần chỉ định cụ thể bám theo Top,Left,Bottom,Right

Mặc định control khai báo trong DockPanel được gán là left

Khi có nhiều Control được bám cùng một kiểu thì sẽ tuân theo thứ tự Control nào khai báo trước thì bám trước

  • Tạo mới DocPanelView.xaml trong LayoutView , mã DocPanelView.xaml như sau :
<DockPanel>
        <TextBlock Text="Control1"
                   DockPanel.Dock="Top"
                   Foreground="#58290A" />
        <Button DockPanel.Dock="Right"
                Content="Control 2" />
        <Button DockPanel.Dock="Bottom"
                Content="Control3" />
        <Button DockPanel.Dock="Right"
                Content="Control 4" />
        <!--Mặc định được gán là left được-->
        <Button Content="Control 5" />
    </DockPanel>
  • Khai báo chạy DocPanelView.xaml trong App.xaml
<Application x:Class="SampleWpf.App"            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="/LayoutView/DocPanelView.xaml">
    <Application.Resources>
    </Application.Resources>
</Application>
  • Chạy ứng dụng được kết quả như hình sau : alt

d/ Canvas

Canvas sắp xếp các Control theo vị trí tuyệt đối bằng việc đặt ví trí top,left

Có thể đặt theo bottom ,right

Nếu đặt đồng thời cả top,left,right,bottom thì sẽ ưu tiên hiển thị theo top,left

Khi khai báo vị trí tuyệt đối bằng canvas các Control khai báo sau có thể chèn nên các Control khai báo trước nếu các vị trí trùng nhau

  • Tạo CanvasView trong thư mục LayoutView với code như sau :
<Canvas>
        <TextBlock Canvas.Top="10"
                   Canvas.Left="20"
                   Text="TextBolok" />
        <Button Canvas.Bottom="25"
                Canvas.Right="50"
                Width="100" Content="Button 1"/>
    </Canvas>
  • Khai báo khởi chạy CanvasView trong App.xaml
    <Application x:Class="SampleWpf.App"            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 StartupUri="/LayoutView/CanvasView.xaml">
        <Application.Resources>
        </Application.Resources>
    </Application>
  • Chạy ví dụ được kết quả như hình sau : alt

e/ Grid

Grid là panel phân chia giao diện làm các dòng và cột.Ta có thể chỉ định các Control lên các ô cụ thể

Grid giống bộ khung table trong html ,chúng ta cũng có thể gép,nối ,chia các cột,dòng

Việc dùng Grid có thể thiết kế tất cả các giao diện

Tuy nhiên với những giao diện đơn giản có thể dùng các Panel như StackPanel,WrapPanel,DockPanel,Canvas bởi vì việc dùng chúng đơn giản hơn nhiều so với dùng Girid

Grid sẽ tự động chia đều các cột dựa vào nội dung Control đặt lên nó.Tức là các cột có bề ngang sẽ luôn bằng nhau

Ngoài ra có thể khai báo thuộc tính width =" * "để grid tự động chỉnh cột theo nội dùng Control .Khi này các cột có chiều ngang có thể không bằng nhau và dựa vào nội dung control đặt trên nó

  • Tạo GridView.xaml trong thư mục LayoutView với mã như sau :
<Window x:Class="SampleWpf.LayoutView.GridView"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="GridView" Height="300" Width="300">
    <Grid ShowGridLines="True">
        <!--Định nghĩa cột-->
        <Grid.ColumnDefinitions>
            <!--Khai báo cột 1.Có chiều ngang gấp đôi cột 2-->
            <ColumnDefinition Width="2*" />
            <!--Khai báo cột 2,không định nghĩa chiều ngang-->
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <!--Định nghĩa dòng.3 hàng -->
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition />
            <RowDefinition Height="2*" />
        </Grid.RowDefinitions>
        <!--Gán Control vào Hàng 0,Cột 0-->
        <Button Content="Button1"
                Grid.Column="0"
                Grid.Row="0" />
        <Button Content="Button2"
                Grid.Column="0"
                Grid.Row="1" />
        <Button Content="Button3"
                Grid.Column="1"
                Grid.Row="2" />
    </Grid>
</Window>
  • Khai báo khở chạy GridView.xaml trong app.xaml

  • Chạy ví dụ được kết quả như hình sau : alt