This article has been localized into Vietnamese by the community.
Điều khiển ComboBox
Combobox control có nhiều cách gọi như là ListBox control, nhưng nó chiếm ít diện tích hơn, vì các Item được ẩn đi khi không cần thiết. Combobox control được sử dụng nhiều chỗ trong Windows, nhưng để đảm bảo mọi người biết nó như thế nào và hoạt động ra sao, chúng ta hãy xem ví dụ đơn giản sau:
<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxSample" Height="150" Width="200">
<StackPanel Margin="10">
<ComboBox>
<ComboBoxItem>ComboBox Item #1</ComboBoxItem>
<ComboBoxItem IsSelected="True">ComboBox Item #2</ComboBoxItem>
<ComboBoxItem>ComboBox Item #3</ComboBoxItem>
</ComboBox>
</StackPanel>
</Window>
Trong hình ảnh màn hình, tôi đã active combobox bằng cách click lên nó vì vậy các item đã hiển thị. Như các bạn thấy từ những dòng code, thì combobox (dạng đơn giản) rất dễ sử dụng. Tất cả được hoàn tất bằng cách thủ công thêm vài item và chọn 1 item làm item mặc định bằng thuộc tính IsSelected trên item đó.
Nội dung tùy chỉnh
Trong ví dụ đầu tiên, chúng tôi chỉ hiện thị text của item, đó là cách dùng phổ biến của combobox control, nhưng vì ComboboxItem là 1 ContentControl, chúng ta có thể thực sự sử dụng nhiều hơn như là content. Hãy làm cho các item tinh vi hơn 1 chút:
<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxCustomContentSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxCustomContentSample" Height="150" Width="200">
<StackPanel Margin="10">
<ComboBox>
<ComboBoxItem>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_red.png" />
<TextBlock Foreground="Red">Red</TextBlock>
</StackPanel>
</ComboBoxItem>
<ComboBoxItem>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_green.png" />
<TextBlock Foreground="Green">Green</TextBlock>
</StackPanel>
</ComboBoxItem>
<ComboBoxItem>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Foreground="Blue">Blue</TextBlock>
</StackPanel>
</ComboBoxItem>
</ComboBox>
</StackPanel>
</Window>
Cho mỗi ComboboxItem chúng ta thêm StackPanel (để thêm hình và TextBlock). StackPanel sẽ giúp tùy chỉnh content cũng như là hiển thị chữ. Như các bạn thấy trong ảnh chụp màn hình, thì màu chữ và hình ảnh điều chỉ đúng giá trị màu.
liên kết Data với Combobox (Data binding)
Như bạn thấy trong ví dụ đầu tiên thì thủ công định nghĩa item của combobox control thì dễ dàng dùng XAML, nhưng bạn sẽ sớm gặp tình huống mà bạn cần item từ nguồn data nào đó, như database hoặc từ bộ nhớ. Sử dụng WPF liên kết data (data binding) và 1 mẫu tùy chỉnh (custom template), chúng ta có thể dễ dàng tạo 1 list màu bao gồm xem trước của màu:
<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxDataBindingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxDataBindingSample" Height="200" Width="200">
<StackPanel Margin="10">
<ComboBox Name="cmbColors">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
namespace WpfTutorialSamples.ComboBox_control
{
public partial class ComboBoxDataBindingSample : Window
{
public ComboBoxDataBindingSample()
{
InitializeComponent();
cmbColors.ItemsSource = typeof(Colors).GetProperties();
}
}
}
Khá đơn giản: trong code dưới đây, tôi lấy danh sách tất cả các màu sử dụng Reflection dựa trên lớp Colors. Tôi gán nó vô thuộc tính ItemsSource của Combobox, nó sẽ tạo từng màu theo mẫu mà tôi đã định nghĩa trong XAML.
Cho từng item, như định nghĩa bởi ItemTemplate, bao gồm StackPanel với 1 thuộc tính Rectangle và 1 thuộc tính TextBlock bị ràng buộc bởi giá trị màu. Từ đây ta sẽ có danh sách màu, code rất nhẹ nhàng và nhìn rất đẹp đúng không?
IsEditable
Trong ví dụ đầu tiên, user chỉ có thể tạo chọn từ danh sách của item, nhưng 1 trong những điểm thú vị về combobox là nó hỗ trợ để người dùng có thể chọn từ danh sách item hoặc nhập giá trị tùy thích. Tình huống này cực kỳ hữu ích nếu bạn muốn cung cấp cho người dùng danh sách lựa chọn được định sẵn, mà vẫn cho họ đưa ra giá trị họ muốn. Thuộc tính IsEditable sẽ tùy chỉnh việc trên, chúng ta hãy xem hoạt động của combobox 1 chút.
<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxEditableSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxEditableSample" Height="150" Width="200">
<StackPanel Margin="10">
<ComboBox IsEditable="True">
<ComboBoxItem>ComboBox Item #1</ComboBoxItem>
<ComboBoxItem>ComboBox Item #2</ComboBoxItem>
<ComboBoxItem>ComboBox Item #3</ComboBoxItem>
</ComboBox>
</StackPanel>
</Window>
Như bạn thấy, bạn có thể nhập 1 giá trị khác, hoặc chọn 1 giá trị trong danh sách. Nếu chọn trong danh sách, nó sẽ viết đè chữ trong Combobox.
Như 1 phần bổ sung nhỏ, Combobox sẽ tự động giúp người dùng lựa chọn giá trị có sẵn khi người dùng nhập chữ, như bạn thấy ở màn hình bên cạnh, khi tôi bắt đầu nhập chữ "Co":
Mặc định, khớp từ khóa không phân biệt hoa thường nhưng bạn có thể cho phân biệt hoa thường bằng cách đổi giá trị IsTextSearchCaseSensitivethành True. Nếu bạn không muốn auto complete (tự hoàn thành), bạn có thể tắt nó đi bằng các đổi giá trị IsTextSearchEnabled thành false.
Làm việc với lựa chọn trong Combobox (Combobox selection)
Phần chỉnh của Combobox control là có thể đọc lựa chọn của người dùng, và xử lý nó trong code. Trong ví dụ tiếp theo, tôi sử dụng lại ví dụ data đã liên kết với Combobox, nhưng thêm vài nút để điều khiển lựa chọn trong combobox. Tôi dùng sự kiện SelectionChanged để bắt khi nào thì item được chọn thay đổi bằng code hoặc bằng người dùng, và hoạt động trên nó.
Đây là ví dụ
<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSelectionSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ComboBoxSelectionSample" Height="125" Width="250">
<StackPanel Margin="10">
<ComboBox Name="cmbColors" SelectionChanged="cmbColors_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<WrapPanel Margin="15" HorizontalAlignment="Center">
<Button Name="btnPrevious" Click="btnPrevious_Click" Width="55">Previous</Button>
<Button Name="btnNext" Click="btnNext_Click" Margin="5,0" Width="55">Next</Button>
<Button Name="btnBlue" Click="btnBlue_Click" Width="55">Blue</Button>
</WrapPanel>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Media;
namespace WpfTutorialSamples.ComboBox_control
{
public partial class ComboBoxSelectionSample : Window
{
public ComboBoxSelectionSample()
{
InitializeComponent();
cmbColors.ItemsSource = typeof(Colors).GetProperties();
}
private void btnPrevious_Click(object sender, RoutedEventArgs e)
{
if(cmbColors.SelectedIndex > 0)
cmbColors.SelectedIndex = cmbColors.SelectedIndex - 1;
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
if(cmbColors.SelectedIndex < cmbColors.Items.Count-1)
cmbColors.SelectedIndex = cmbColors.SelectedIndex + 1;
}
private void btnBlue_Click(object sender, RoutedEventArgs e)
{
cmbColors.SelectedItem = typeof(Colors).GetProperty("Blue");
}
private void cmbColors_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
Color selectedColor = (Color)(cmbColors.SelectedItem as PropertyInfo).GetValue(null, null);
this.Background = new SolidColorBrush(selectedColor);
}
}
}
Phần thú vụ của ví dụ này là 3 xử lý sự kiện cho 3 nút, cũng như xử lý sự kiên SelectionChanged. Trong 2 cái đầu, tôi chọn item trước và item sau bằng cách đọc thuộc tính SelectedIndex sau đó trừ 1 hoặc cộng 1. Thật đơn giản và dễ dàng.
Trong xử lý sự kiện thứ 3, tôi dùng SelectedItem để chọn 1 item đặc biệt dựa trên giá trị. Tôi thực hiện bằng .net reflection, vì Combobox được ràng buộc với danh sách thuộc tính mà mỗi thuộc tính là màu, thay vì đơn giản là danh sách màu. Nhưng cơ bản là giá trị gồm 1 trong những Item trong thuộc tính SelectedItem.
Trong xử lý sự kiện thứ 4 và cuối cùng, tôi phản hồi item bị thay đổi. Khi item thay đổi, tôi đọc màu được chọn (một lần nữa dùng Reflection, như mô tả ở trên) và sau đó dùng màu chọn để tạo cọ vẽ nền cho màn hình. Hiệu úng có thể nhìn trên ảnh chụp màn hình.
Nếu bạn làm việc với Combobox có thể chỉnh sửa (thuộc tính IsEditable = true), bạn có thể đọc thuộc tính Text để biết giá trị người dùng đã nhập hoặc đã chọn.