You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# UWP程序化实现用户自定义检查表的入门困惑求助

一步步实现UWP自定义检查表功能

刚接触XAML确实容易有点无从下手,别担心,咱们从数据模型到UI再到逻辑一步步来搞定这个检查表功能~

第一步:定义层级任务的数据模型

首先咱们需要一个能表示「任务+子任务」的类,还要让它支持UI自动更新,所以得实现INotifyPropertyChanged接口:

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace Table1
{
    public class CheckItem : INotifyPropertyChanged
    {
        private string _title;
        private bool _isChecked;
        private ObservableCollection<CheckItem> _children;

        // 任务标题
        public string Title
        {
            get => _title;
            set
            {
                _title = value;
                OnPropertyChanged();
            }
        }

        // 是否勾选
        public bool IsChecked
        {
            get => _isChecked;
            set
            {
                _isChecked = value;
                OnPropertyChanged();
                // 可选功能:勾选父任务时自动勾选所有子任务,反之同理
                foreach (var child in Children)
                {
                    child.IsChecked = value;
                }
            }
        }

        // 子任务集合,用ObservableCollection能自动通知UI更新
        public ObservableCollection<CheckItem> Children
        {
            get => _children ??= new ObservableCollection<CheckItem>();
            set
            {
                _children = value;
                OnPropertyChanged();
            }
        }

        // 属性变更通知事件
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

第二步:设计UI界面

因为是层级结构,用TreeView比ListBox更适合展示(当然如果坚持用ListBox也可以,我会在注释里标注替换方式)。咱们把输入区和显示区分开:

<Page x:Class="Table1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:Table1"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">

    <Grid Padding="20">
        <Grid.RowDefinitions>
            <!-- 输入区域行:自动高度 -->
            <RowDefinition Height="Auto"/>
            <!-- 检查表显示行:占满剩余空间 -->
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- 输入任务的区域 -->
        <StackPanel Grid.Row="0" Orientation="Horizontal" Spacing="10" Margin="0 0 0 15">
            <TextBox x:Name="InputTextBox" 
                     PlaceholderText="输入任务/子任务标题" 
                     Width="350"/>
            <Button x:Name="AddBtn" 
                    Content="添加" 
                    Click="AddBtn_Click"/>
        </StackPanel>

        <!-- 层级检查表显示区(TreeView版本) -->
        <TreeView x:Name="CheckTreeView" Grid.Row="1">
            <TreeView.ItemTemplate>
                <!-- 用HierarchicalDataTemplate绑定层级数据 -->
                <HierarchicalDataTemplate x:DataType="local:CheckItem" 
                                          ItemsSource="{Binding Children}">
                    <StackPanel Orientation="Horizontal" Spacing="8">
                        <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" 
                                  VerticalAlignment="Center"/>
                        <TextBlock Text="{Binding Title}" 
                                   FontSize="14" 
                                   VerticalAlignment="Center"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

        <!-- 如果坚持用ListBox,替换上面的TreeView为这段:
        <ListBox x:Name="CheckListBox" Grid.Row="1">
            <ListBox.ItemTemplate>
                <HierarchicalDataTemplate x:DataType="local:CheckItem" 
                                          ItemsSource="{Binding Children}">
                    <StackPanel Orientation="Horizontal" Spacing="8">
                        <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" 
                                  VerticalAlignment="Center"/>
                        <TextBlock Text="{Binding Title}" 
                                   FontSize="14" 
                                   VerticalAlignment="Center"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        -->
    </Grid>
</Page>

第三步:实现添加逻辑

在后台代码里处理按钮点击事件,判断当前选中的任务,把输入的内容添加到对应位置:

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Collections.ObjectModel;

namespace Table1
{
    public sealed partial class MainPage : Page
    {
        // 存储所有根任务的集合
        private ObservableCollection<CheckItem> _checkList;

        public MainPage()
        {
            this.InitializeComponent();
            // 初始化数据源
            _checkList = new ObservableCollection<CheckItem>();
            CheckTreeView.ItemsSource = _checkList;
            // 如果用ListBox,替换成:CheckListBox.ItemsSource = _checkList;
        }

        private void AddBtn_Click(object sender, RoutedEventArgs e)
        {
            var inputContent = InputTextBox.Text.Trim();
            // 空内容不处理
            if (string.IsNullOrEmpty(inputContent)) return;

            // 创建新的任务项
            var newCheckItem = new CheckItem { Title = inputContent };

            // 获取当前选中的任务(TreeView版本)
            var selectedItem = CheckTreeView.SelectedItem as CheckItem;
            // 如果用ListBox,替换成:var selectedItem = CheckListBox.SelectedItem as CheckItem;

            if (selectedItem != null)
            {
                // 有选中项,添加为它的子任务
                selectedItem.Children.Add(newCheckItem);
            }
            else
            {
                // 没有选中项,添加为根任务
                _checkList.Add(newCheckItem);
            }

            // 清空输入框
            InputTextBox.Text = string.Empty;
        }
    }
}

额外小提示

  • 如果要支持删除任务,可以加个删除按钮,获取选中项后,判断它是否是根任务(从_checkList移除)还是子任务(从父项的Children移除)。
  • 如果要支持编辑标题,可以把TextBlock换成TextBox,绑定Title属性,设置IsReadOnly默认true,双击后改为false编辑。

内容的提问来源于stack exchange,提问作者Morilynx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:39:39