ComboBox phân cấp đa lựa chọn cho Silverlight

MultiLevelMultiSelectComboBox là một điều khiển tùy chỉnh mở rộng khả năng của ComboBox gốc trong môi trường Silverlight, cho phép hiển thị dữ liệu phân cấp (cây) và hỗ trợ chọn đồng thời nhiều mục ở nhiều cấp độ khác nhau.

Khác với ComboBox tiêu chuẩn — chỉ hỗ trợ danh sách phẳng và lựa chọn đơn — thành phần này tích hợp TreeView bên trong thông qua ItemTemplate, kết hợp với HierarchicalDataTemplate để biểu diễn cấu trúc cha-con. Mỗi nút trong cây được gắn kèm một CheckBox, cho phép người dùng kiểm soát trạng thái chọn theo ngữ cảnh phân cấp: khi chọn một nút cha, các nút con có thể được chọn tự động hoặc ngược lại, tùy vào logic xử lý.

Dưới đây là phiên bản đã tái cấu trúc của mẫu XAML, sử dụng tên thuộc tính rõ ràng hơn, lược bỏ các thẻ thừa và tối ưu hóa bố cục:

<UserControl.Resources>
  <sdk:HierarchicalDataTemplate x:Key="TreeTemplate" ItemsSource="{Binding Children}">
    <Grid HorizontalAlignment="Stretch">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
      </Grid.ColumnDefinitions>

      <CheckBox Grid.Column="0"
                 IsChecked="{Binding IsSelected, Mode=TwoWay}"
                 VerticalAlignment="Center"
                 Margin="2,0,4,0" />

      <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
        <Image Source="{Binding IconUri}" Width="16" Height="16" Margin="0,0,4,0" />
        <TextBlock Text="{Binding DisplayName}" VerticalAlignment="Center" />
      </StackPanel>
    </Grid>
  </sdk:HierarchicalDataTemplate>
</UserControl.Resources>

<sdk:ComboBox x:Name="MainCombo"
              Height="26"
              HorizontalContentAlignment="Stretch">
  <sdk:ComboBox.ItemTemplate>
    <DataTemplate>
      <sdk:TreeView ItemsSource="{Binding ElementName=MainCombo, Path=Tag}"
                     ItemTemplate="{StaticResource TreeTemplate}"
                     HorizontalAlignment="Stretch" />
    </DataTemplate>
  </sdk:ComboBox.ItemTemplate>
</sdk:ComboBox>

Để điều khiển hành vi và dữ liệu, lớp điều khiển khai báo các DependencyProperty như sau:

public static readonly DependencyProperty NodeSourceProperty =
  DependencyProperty.Register(
    nameof(NodeSource),
    typeof(IEnumerable<TreeNode>),
    typeof(MultiLevelMultiSelectComboBox),
    new PropertyMetadata(OnNodeSourceChanged));

public IEnumerable<TreeNode> NodeSource
{
  get => (IEnumerable<TreeNode>)GetValue(NodeSourceProperty);
  set => SetValue(NodeSourceProperty, value);
}

private static void OnNodeSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  if (d is MultiLevelMultiSelectComboBox control)
    control.RefreshTree();
}

Các thuộc tính quan trọng bao gồm:

  • NodeSource: Danh sách gốc chứa các nút phân cấp kiểu TreeNode. Mỗi phần tử phải thiết lập đúng tham chiếu ParentChildren để đảm bảo tính toàn vẹn của cây.
  • EnableSelectAll: Kích hoạt mục "Chọn tất cả" ở đầu danh sách, cho phép chọn hoặc hủy chọn toàn bộ cây bằng một thao tác.
  • SelectedNodes: Thuộc tính đọc-only trả về tập hợp các nút đang được chọn, bao gồm cả thông tin cấp bậc và trạng thái chọn riêng lẻ.

Khi sử dụng trong XAML, điều khiển được khai báo ngắn gọn và ràng buộc dữ liệu hai chiều:

<local:MultiLevelMultiSelectComboBox
  NodeSource="{Binding CategoryTree}"
  SelectedNodes="{Binding ChosenCategories, Mode=TwoWay}"
  EnableSelectAll="True"
  Width="320" />

Thẻ: Silverlight ComboBox TreeView HierarchicalDataTemplate DependencyProperty

Đăng vào ngày 17 tháng 8 lúc 17:16