WPF và MVVM – Phần 4: Ứng dụng trong WPF

Một khái niệm dễ nhầm lẫn khá phổ biến mà tôi thấy mọi người khi bắt đầu với WPF là họ cảm thấy rằng đó là khó tiếp cận, quá phức tạp và quá cồng kềnh. Có một số thay đổi cơ bản mà mỗi lập trình viên phải xử lý khi lần đầu tiên chuyển sang WPF, nhưng thực sự không đáng kể lắm. Bạn có thể lập trình với API của Windows Presentation Foundation bằng cách sử dụng các kỹ thuật cơ bản cùng các kỹ thuật mà bạn đã sử dụng trong Windows Forms.

Điều đầu tiên bạn cần chú ý khi làm việc với WPF là sự thay đổi trong cách thức hoạt động của các nhà thiết kế. Một số khái niệm giống nhau – bạn có thể kéo các controls sang một Window hay một UserControl và di chuyển chúng xung quanh, thực hiện các layout,… Có một số khác nhau trong cách thức làm việc, đặc biệt là trong trường hợp layout nhưng hầu hết các lập trình viên vẫn có thể mở một cửa sổ, kéo thả các controls sử dụng cùng các kỹ thuật cơ bản như người thiết kế Windows Forms.

Tuy nhiên, khi hoàn thành việc này, người thiết kế sẽ thực hiện một số thứ rất khác biệt. Trong Windows Forms, người thiết kế viết mã nguồn cho chúng ta dưới dạng một lớp partial class và trong file .designer.cs, chúng ta có tất cả mã nguồn để tạo ra giao diện người dùng. Điều này phù hợp với phong cách lập trình mệnh của Windows Forms. Mặt khác, nhà thiết kế WPF thay vào đó sẽ xây dựng giao diện người dùng bằng cách tạo file .xaml, sử dụng Ngôn ngữ đánh dấu ứng dụng mở rộng (Extensible Application Markup Language). Microsoft mô tả XAML như “Một ngôn ngữ khai báo hỗ trợ điều khiển luồng” (“A Declarative Language with Flow Control Support”) từ khóa ở đây chính là “khai báo” (declarative). WPF sử dụng mô hình lập trình dạng khai báo, ít nhất ở đây là cho việc tạo giao diện người dùng. Thay vì xác định các bước cần yêu cầu để xây dựng giao diện người dùng, trình biên dịch sử dụng file đánh dấu (dựa trên XML) mô tả những gì sẽ hiển thị, không làm thế nào để hiển thị nó.

Đây chính là thay đổi cơ bản cần phải có trong cách tư duy khi sử dụng WPF. Thậm chí, điều này được kiểm soát hoàn toàn bởi người thiết kế, do đó về mặt kỹ thuật, bạn có thể xây dựng toàn bộ giao diện người dùng và không cần phải nhìn vào nó, cũng giống như bạn có thể xây dựng một giao diện người dùng Windows Forms và không cần nhìn vào file thiết kế.

WPF cũng cung cấp các sự kiện tương tự, thường thì giống hệt nhau. Chẳng hạn như, Button cung cấp sự kiện Click chuột, để bạn có thể đăng ký sự kiện. Điều khiển TextBox cung cấp thuộc tính Text để bạn thiết lập thuộc tính này. Điều này cho phép bạn kích hoạt các bộ xử lý sự kiện theo nghĩa gần như với Windows Forms.

Phần này của chuỗi bài viết sẽ minh họa điều này. Chúng ta sẽ viết cùng ứng dụng đã viết bằng Windows Forms ở phần 3, nhưng ở đây sẽ dùng WPF.

Điều cần chú ý trước tiên – ứng dụng sẽ tương tự với ứng dụng ở phần 3:

Các khác biệt chủ yếu ở đây là do các thay đổi trong phong cách mặc định của các controls WPF so với Windows Forms. Về mặt chức năng thì 2 ứng dụng này là giống hệt nhau. Nó sử dụng cùng các lớp Model và hoàn toàn không thay đổi. Tôi thực hiện cùng các chức năng với cùng các hành vi cơ bản giống nhau. Thậm chí chúng tôi cấu trúc nó theo cùng một cách, sử dụng UserControl cho phần trung tâm của Window.

Khi nhìn vào mã nguồn, chúng ta thấy một số điều rất ngạc nhiên – mã nguồn gần như giống hệt với ứng dụng Windows Forms đã xây dựng. Ví dụ như, nút “Load RSS Feed” trong lớp Window chính có một bộ kiểm soát sự kiện click gắn liền với nó, và giống như ứng dụng Windows Forms của chúng ta, nó không làm gì ngoài việc load Feed bằng cách sử dụng Model và thiết lập một thuộc tính trong UserControl. Khác biệt duy nhất ở đây là trong khai báo phương thức của chúng ta: thay vì chuyển EventArgs e, bây giờ chúng ta sẽ chuyển RoutedEvenArgs e. Ngoài ra, mã nguồn là giống nhau:

private void ButtonUpdateFeed_Click(object sender, RoutedEventArgs e)
{
    this.feedControl.Feed = Feed.Read(new Uri(this.textBoxFeedUrl.Text));
}

Cũng giống như trên, cái này cũng thiết lập thuộc tính “Feed” bên trong UserControl nhưng lần này, mã nguồn trong UserControl của chúng ta hoàn toàn giống như với mã nguồn trong Windows Forms. Chúng ta có thể sao chép mã nguồn mà hoàn toàn không thay đổi gì từ Windows Forms sang WPF. Đây chỉ là một phần nhỏ của mã nguồn này, chỉ minh họa rằng nó không thay đổi gì:

// ... previous code from Windows Forms application
    this.textBoxTitle.Text = this.Feed.Title;
    this.textBoxLink.Text = this.Feed.Link.AbsoluteUri;
    this.textBoxDescription.Text = this.Feed.Description;

    foreach (var item in this.Feed.Items)
    {
        this.listBoxFeeds.Items.Add(item.Title);
    }
// ... continue with code from Windows Forms application

Thực tế, khi chúng ta nhìn vào mã nguồn bên trong của UserControl (file có định dạng .xaml.cs), khác nhau duy nhất giữa mã nguồn WPF và Windows Forms, thông qua toàn bộ Window và UserControl, là sự khác biệt trong phương thức khai báo và thiết lập “.Source” thay vì “.Url” trong cửa sổ chính Main, vì WPF có các khai báo đại diện (delegate) khác cho các sự kiện của nó và một số khác biệt trong controls APIs. Nói tóm lại, mã nguồn chúng ta viết là giống hệt nhau.

Windows Presentation Foundation, mặc dù mới mẻ nhưng không bắt buộc các nhà phát triển phải thay đổi phong cách lập trình của mình. Chúng ta có thể làm mọi thứ theo cách chúng ta đã làm với Windows Forms và tiếp tục với các công nghệ mới hơn. Thậm chí chúng ta có thể kết hợp Windows Forms với WPF thông qua ElementHost và WindowsFormsHost cho phép chúng ta host WPF bên trong Windows Forms và Windows Forms từ bên trong WPF.

Dưới đây là những điểm quan trọng cần chú ý trong phần này của chuỗi bài viết:

  • Mặc dù WPF là một API hoàn toàn mới nhưng bạn có thể sử dụng cùng
    phong cách lập trình hướng sự kiện mà bạn đã sử dụng trong Windows
    Forms.
  • Hầu hết các tính năng mới trong WPF đều có thể tùy chọn. Bạn có thể
    xây dựng một ứng dụng WPF thực tế sử dụng cùng kỹ thuật như Windows
    Forms, chỉ khác biệt duy nhất ở đây là một số giao diện được định
    nghĩa theo kiểu khai báo thay vì hoàn toàn theo kiểu mệnh lệnh.

Hy vọng rằng những điều này sẽ giúp cho bạn bớt lo lắng khi chuyển từ Windows Forms sang WPF. Thực sự không có lý do gì để tránh thiết kế ứng dụng sử dụng Windows Presentation Foundation, ngay cả khi tôi đã không(chưa) mô tả được những lý do chính đáng, thuyết phục cũng như chưa nêu hết các lợi thế của WPF để bạn thực hiện sự chuyển đổi này.

4 Likes

@DuyNguyen cho thêm vài cái hình cho nó trực quan đi :slight_smile: Đạt không làm về C# và WPF nên không biết nhận xét thế nào về phần nội dung

Cám ơn bạn về bài viết nhưng mình đọc vào vẫn cảm thấy cách giải thích chưa được rõ ràng lắm. Có thể là do dịch từ bản tiếng anh.
Mình nghĩ là bạn đọc xong, bạn hiểu như thế nào rồi giải thích theo cách bạn hiểu, có lẽ sẽ dễ hiểu hơn.

ví dụ như đoạn này:

Microsoft mô tả XAML như “Một ngôn ngữ khai báo hỗ trợ điều khiển luồng” (“A Declarative Language with Flow Control Support”) từ khóa ở đây chính là “khai báo” (declarative). WPF sử dụng mô hình lập trình dạng khai báo, ít nhất ở đây là cho việc tạo giao diện người dùng. Thay vì xác định các bước cần yêu cầu để xây dựng giao diện người dùng, trình biên dịch sử dụng file đánh dấu (dựa trên XML) mô tả những gì sẽ hiển thị, không làm thế nào để hiển thị nó.

Như mình hiểu thì XAML là một dạng mở rộng của XML, dùng để mô tả các thông tin về giao diện, cách một control hiển thị trên màn hình, các thông số của các control ví dụ như : width, heigh, background, position … , gắn các sự kiện của control với các hàm xử lý trong file code c#. Ngoài ra nó còn cho phép định nghĩa các thông tin về style, animation, resource …

Một control/view trong WPF gồm có 2 phần, phần định nghĩa giao diện như đã nói ở trên, phần code xử lý bằng C#. Làm sao để 2 phần này kết hợp với nhau để tạo nên 1 control/view hoàn chỉnh.
Từ version 2.0, C# có thêm khái niệm là partial class. Nó cho phép phân chia định nghĩa của 1 class thành nhiều file khác nhau. Khi build nó sẽ kết hợp lại với nhau tạo thành 1 class hoàn chỉnh.
Trong WPF khi chương trình compile, đầu tiên từ file XAML sẽ generate ra một file source C# có phần mở rộng là .g.cs sau đó nó sẽ kết hợp với file code xử lý để tạo thành một class hoàn chỉnh. Do đó từ trong file source C# có thể sử dụng các control được khai báo trong file XAML.

vâng a, e sẽ cố gắng thêm hình vào để cho trực quan.

XAML là dựa trên XML nhưng khác chỗ XML là ngôn ngữ đánh dấu dữ liệu còn XAML là ngôn ngữ đánh dấu để thể hiện giao diện nên nó khá giống với HTML đó bạn từ các property, và như bạn nói cho phép định nghĩa style, animation…ngoài ra còn có cơ chế BindingData, TemplateBinding, Resource…rất mạnh mẽ để liên kết dữ liệu hay liên kết giữa properties của 1 template với các properties của control, phần sau sẽ nói đến những thứ này :smile:

Bạn nói đúng, do có sự xuất hiện của XAML đã phá vỡ bức tường giữa Developer và Designer, trước kia khi phát triển ứng dụng Winforms thì công việc của cả Developer và Designer rất nặng, yêu cầu cả 2 bên phải có hiểu biết về nhiều công cụ. Còn trong quá trình phát triển ứng dụng WPF, công việc của Designer và Developer đều được giảm nhẹ do Developer và Designer cóthể chia sẻ với nhau đoạn mã XAML chung, tách biệt phần giao diện ra khỏi Code-behind.

Cám ơn bạn đã góp ý, mình sẽ chú ý hơn phần này :smiley:

4 Likes

WPF, mình thấy trang http://www.wpftutorial.net/ chất lượng cho nguoi mới bắt đầu.
tiếng việt thì tham khảo của https://yinyangit.wordpress.com/
@DuyNguyen cá nhân mình thấy bài dịch của bạn rất tốt, nhưng hơi nhiều thông tin cho người mới làm quen WPF. mình thấy nên bắt đầu bằng ví dụ đơn giản.
thanks.

2 Likes

WPF.
Làm GUI ngon lắm :smiley:
Show vài cái hình anh em thưởng thức (tuy chưa có gì @@).

2 Likes

Định học cái này , nhưng nghành em là CE nên lập trình C# chỉ là phụ thôi vì em là bên Embedded System . Mong a @ltd nói cho em biêt cái này học thê nào và tốn khoảng bao lâu và ích lợi của nó là gì :smiley:

Thật sự thì WPF làm GUI cũng như Winform thôi bạn ah. Cái hay của nó là áp dụng được MVVM pattern kia. GUI bạn có thể dùng Blend để thiết kế. :slight_smile:

Sao lại như WinForm hả bạn ?
Như WinForm ở điểm nào vậy ?

đang tìm hiểu về cái này … Hóng :slight_smile:

Winform làm GUI thì kéo và thả :grinning: có vẻ khô cứng , còn WPF thì mình thấy nó rất mềm dẻo nhờ có XAML

Mình đang dùng và thấy rất khoái. Chắc tại tánh ưa màu mè :grinning:

cho em hỏi WPF có thể làm Web Application được ko ạ ? kiểu như asp.net mvc á

Em tìm hiểu XBAP nhé.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?