[Basic for Absolute Beginner] – [Part 2] – Layout with XAML

Đây là phần 2 của loạt bài viết Layout with XAML – Basic for Absolute Beginner

Bài 1 ở đây: [Windows Phone – Silverlight] Layout with XAML – Basic for AbsoluteBeginner – Part 1

Như các bạn đã biết, ngoài Stackpanel và Grid ra, XAML còn có 1 control cơ bản khác, đó là ListBox (và GridView, ListView, nếu bạn đang lập trình cho Windows 8 hay các ứng dụng WPF)

Trong phạm vi bài viết này, mình sẽ đề cập tới ListBox cùng cách thiết kế nó trên giao diện.

  1. LISTBOX CONTROL

ListBox control dùng để hiện thị một danh sách các item.

Danh sách này sẽ có một giao diện nhất định, một kiểu dữ liệu nhất định tùy bạn chọn

Ví dụ: “Top 30 video được xem nhiều nhất trên youtube” là một dạng dữ liệu mà ta sẽ dùng ListBox để hiển thị

  1. Các thuộc tính quan trọng

1.1.1 ItemsSource

ItemsSource là nguồn dữ liệu. Listbox này sẽ hiển thị dữ liệu từ đâu?

ItemsSource có thể là một List hoặc một ObservableCollection, ta sẽ nói đến nó ở phần sau

1.1.2 SelectedIndex

Cái tên đã nói lên tất cả. Đây là item đang được chọn trong listbox của bạn. Trong quá trình khởi tạo, giá trị này sẽ là -1

Lưu ý rằng item bắt đầu từ số 0 trở đi. Giả sử bạn có 5 items, thì nó sẽ được đánh số từ 0 tới 4

1.1.3 SelectedItem

Đây lại là một thuộc tính khác. Giá trị của thuộc tínhnày bằng null khi khởi tạo. Và khi người dùng chọn một item nào đó trong listbox, item đó sẽ được phản xạ sang thuộc tính này.

Thuộc tính này có kiểu dữ liệu là Object, khi dùng bạn phải ép kiểu sang kiểu dữ liệu của danh sách

1.1.4 DataConext – ngữ cảnh dữ liệu

DataContext sẽ được dùng trong một số trường hợp advance binding, hiện tại thì bạn chưa cần phải quan tâm tới nó

1.2 Thử nghiệm

Tạo một project Windows Phone

Trong LayoutRootGrid, tạo một Listbox

Chọn thẻ Property khi đang select listbox này

Trong mục Items, bạn thêm mới một số item cho listbox

Sau đó, chọn Listbox Item, rồi nhấn nút Add

Như bạn có thể thấy, một item với index = xuất hiện cùng thuộc tính của nó

Rồi thêm vào content như hình sau:

Nhấn nút chạy thử, và bạn sẽ thấy cách hoạt động của listbox

http://youtu.be/8cu_REIkxPQ

Bây giờ bạn đã nắm cách thức Listbox hoạt động cơ bản nhất. Ta hãy cùng “Đào sâu” vào thế giới XAML nhé

  1. DataBinding – Phương pháp tuyệt vời để hiển thị dữ liệu

Listbox được dùng nhiều nhất với kỹ thuật DataBinding này (tạm dịch là gắn kết dữ liệu đi)

Kỹ thuật này cho phép bạn hiển thị dữ liệu từ một nguồn nào đó lên trên listbox. Nguồn đó có thể là một List, hoặc một Observable Collection

Nhiều người khi nghĩ tới DataBinding, họ sẽ nghĩ ngay tới mô hình MVVM.

Khoan đã, trong vai một người mới học, hẳn bạn cũng sẽ không biết MVVM là cái gì, mặt mũi nó ra sao.

Vì vậy, hãy tìm hiểu một số khái niệm và cách thức cơ bản trước đã

2.1 Chuẩn bị

Để thực hiện theo bài viết này, bạn cần có các công cụ sau:

Visual Studio, chắc cái này bạn có rồi

ReSharper: hỗ trợ cho bạn tự động hóa các công việc nhàm chán nhưng cần thiết. Lưu ý đây là phần mềm thương mại

Sau khi cài ReSharper, hãy tiếp tục bài viết nhé

2.2 Kiểu dữ liệu

Để gắn dữ liệu lên ListBox, ta cần phải có một “Nguồn dữ liệu”, và nguồn dữ liệu đó phải được tạo ra bởi một kiểu dữ liệu nào đó, vì nó là một danh sách các item

Ví dụ: một danh sách các chuỗi, một danh sách các số nguyên

Tuy nhiên, bạn cũng có thể tạo ra kiểu dữ liệu riêng của mình, như kiểu “Danh sách các món ăn”

Vậy tạo ra kiểu dữ liệu như thế nào?

Tạo một Folder mới, đặt tên là Model

Hãy tạo một file class mới trong folder đó với tên gọi DataStructure

Một class DataStructure mới được tạo ra. Bạn có thể xóa nó đi, và bắt đầu định nghĩa cho class riêng của mình

Theo như hình trên, bạn có 3 thuộc tính private. Khoan đã, private không thể truy cập ngoài class, nên ta cần tạo các public property cho chúng

Trước khi tạo các public property, ta nên làm một chuyện khác, đó là khai báo Interface INotifyPropertyChanged

Interface này giúp cho việc binding dữ liệu lên giao diện được “liên tục”. Tức là khi có một sự thay đổi về mặt dữ liệu trong nguồn dữ liệu, sự thay đổi đó sẽ lập tức được hiển thị trên giao diện.

Giả sử như bạn có 5 FoodItem, với 5 tên khác nhau. Bạn muốn thay đổi tên của item thứ 2, bạn chỉ cần truy xuất tới item 2 và thay đổi giá trị của thuộc tính foodName, trên giao diện sẽ tự động thay đổi theo mà không cần thêm một dòng code nào cả

Okie, khai báo thuộc tính nào

Bạn phải bắt buộc khai báo thêm 1 event và một Method trong class của mình sau khi khai báo Interface

public
event
PropertyChangedEventHandler PropertyChanged;


protected
virtual
void OnPropertyChanged([CallerMemberName] string propertyName =
null)

{


PropertyChangedEventHandler handler = PropertyChanged;


if (handler !=
null) handler(this, new
PropertyChangedEventArgs(propertyName));

}

Nếu bạn có ReShaper, thì mọi việc đơn giản hơn nhiều

Tiếp tục chọn Yes nhé

Và bạn sẽ thấy kết quả

Lưu ý là ReSharper sẽ thêm một file vào Property của Project bạn đang viết

File Dropbox cho bạn nào không có ReSharper: https://db.tt/ycsvjt1S

Rồi, bây giờ ta sẽ tạo các Public Property

Một lần nữa, ReSharper sẽ giúp ích chúng ta.

Đặt con trỏ vào dưới các thuộc tính Private, chọn ReShaper > Edit > Generate Code…

Chọn Property cho hộp thoại hiện ra

Check cả 3 thuộc tính, check luôn tùy chọn “Notify on Property Changes”

Thế là bạn có 3 thuộc tính đúng chuẩn như sau

2.3 Nguồn dữ liệu

Bạn đã có 1 kiểu dữ liệu, bây giờ bạn sẽ cần 1 nguồn dữ liệu

Tạo một Folder mới tên Data

Tạo một class mới tên StaticData trong Folder đó

Khai báo một biến static ObservableCollection

Khi có ReSharper, nó sẽ tự động thêm các Namespace cần thiết cho bạn. Ở đây, class FoodItem thuộc namespace TestAd.Model

Kết quả là bạn có như sau:

2.4 Nạp dữ liệu

Bây giờ, ta sẽ nạp dữ liệu vào ObservableCollection này

Mở file code behind của page có chứa listbox mà bạn đã tạo trong phần 1

Khai báo như sau, bạn sẽ thấy kiểu khai báo này quen thuộc trong bài: [Windows Phone] Where to put LoadData method

Bước 1: kiểm tra dữ liệu đã tồn tại

Đặc trưng cơ bản của cách khai báo LoadData như thế này là khi ta navigate tới trang này, hoặc có sự thay đổi về elements trên giao diện, event OnLoaded sẽ được gọi lại.

Vì vậy, ta chỉnh sửa event OnLoaded để ngăn ngừa việc load lại dữ liệu như sau:

private
void OnLoaded(object sender, RoutedEventArgs routedEventArgs)

{


if (StaticData.FoodItemCollection.Count ==
0)

{

LoadData();

}

}

Thêm một số code như sau vào hàm LoadData

private
void LoadData()

{


for (int i =
0; i <
5; i++)

{


FoodItem foodItem =
new
FoodItem();

foodItem.Id = i;

foodItem.FoodName =
“Food Name is “
+ i;

foodItem.ImageLink =
“FoodItem_”
+ i +
“_imageLink”;


StaticData.FoodItemCollection.Add(foodItem);

}

}

Mục tiêu của đoạn code trên là add 5 item giả vào FoodItemCollection.

2.5 Binding

Vậy ta đã có dữ liệu, có nguồn dữ liệu, có luôn listbox, bây giờ ta sẽ tiến hành binding dữ liệu này vào listbox

Việc này được thực hiện bởi 1 dòng code duy nhất.

Đặt tên cho listbox của bạn:

Sửa event OnLoaded lại như sau:

private
void OnLoaded(object sender, RoutedEventArgs routedEventArgs)

{


if (StaticData.FoodItemCollection.Count ==
0)

{

LoadData();

FoodListBox.ItemsSource =
StaticData.FoodItemCollection;

}

}

Sau đó, bấm chạy thử trên Emulator hay trên Device tùy thích

Và đây chính là thành quả của các bạn

2.6 DataTemplate

Vậy là dữ liệu đã được hiển thị trên giao diện, nhưng không theo cách bạn mong muốn

Chính vì thế, ta sẽ tạo một DataTemplate cho Listbox, mục đích là để “định nghĩa” cách hiển thị dữ liệu

Vào code XAML của bạn, bấm chọn Document Outline

Document Outline là nơi thể hiện toàn bộ mọi thứ có trên giao diện của bạn dưới dạng cây

Bấm chuột phải vào ListBox của bạn và chọn

Đặt tên cho DataTemplate của bạn rồi nhấn OK

Nếu bạn chọn Define in Application, DataTemplate này có thể được dùng ở mọi page trong project của bạn mà không cần phải khai báo lại

Trong lúc thiết kế, bạn có thể thấy thiết kế của mình được hiển thị trực quan

Nhấn chạy một lần nữa, và mọi thứ sẽ đúng như ý bạn

  1. Event Handling

Vậy là bạn đã có 1 listbox, bây giờ ta sẽ áp dụng một số sự kiện cho nó để thông báo cho người dùng biết họ đã chọn Listbox nào

Trong Property của FoodListBox, chọn nút Event

Double Click vào event “Selection Changed” để khai báo event

Thêm đoạn code sau vào event mới được tạo

if (FoodListBox.SelectedIndex !=
1)

{


FoodItem foodItem = FoodListBox.SelectedItem as
FoodItem;


MessageBox.Show(foodItem.FoodName);

}

Chạy thử và chọn một item bất kỳ

Thật tuyệt vời phải không

Vậy là hết rồi, hẹn gặp lại các bạn ở episode tiếp theo của Series Absolute Beginner nhé

Advertisements

6 thoughts on “[Basic for Absolute Beginner] – [Part 2] – Layout with XAML

  1. Pingback: [Basic for Absolute Beginner] – [Part 3] – App’s Structure and how customized it | C++/C#

  2. anh cho em hỏi là anh cài ReSharper trên bản visual nào? Và em không cài đặt được nó trên Visual Studio Express 2012 for Windows phone

  3. Pingback: [Basic for Absolute Beginner] – [Part 4] – Basic Steps for a new app | C++/C#

  4. Pingback: [Basic for Absolute Beginner] – [Part 6] – Source Control | C++/C#

  5. Pingback: [Not so Basic] – Solve your problems | Tuan Tran's Blog

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