大家好!在之前中我们学习了DataGrid的基础生成,今天来深入探讨DataGrid的各种高级功能和实用技巧,让你的数据展示更加专业和强大!

一、数据绑定和更新技巧
// 使用ObservableCollection实现自动更新public ObservableCollection<Employee> Employees { get; } = new ObservableCollection<Employee>();private void LoadData(){    Employees.Clear();    foreach (var emp in GetEmployeesFromDatabase())    {        Employees.Add(emp);    }}private void AddNewEmployee(Employee employee){    Employees.Add(employee); // 界面自动更新!}private void UpdateEmployee(int index, Employee updatedEmployee){    Employees[index] = updatedEmployee; // 自动更新!}

2. 数据源切换

// 动态切换不同的数据源public void SwitchDataSource(List<Employee> newData){    dataGrid.ItemsSource = null; // 先清空    dataGrid.ItemsSource = newData; // 设置新数据源}// 使用CollectionViewSource进行高级数据操作public void SetupCollectionView(){    ICollectionView view = CollectionViewSource.GetDefaultView(Employees);    view.Filter = item => FilterEmployee(item as Employee);    view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));}
二、列功能增强

1. 动态列管理

// 动态添加列private void AddDynamicColumn(string header, string bindingPath){    DataGridTextColumn column = new DataGridTextColumn    {        Header = header,        Binding = new Binding(bindingPath),        Width = new DataGridLength(1, DataGridLengthUnitType.Star)    };
    dataGrid.Columns.Add(column);}// 动态移除列private void RemoveColumn(string header){    var column = dataGrid.Columns.FirstOrDefault(c => c.Header.ToString() == header);    if (column != null)    {        dataGrid.Columns.Remove(column);    }}// 显示/隐藏列private void ToggleColumnVisibility(string header, bool isVisible){    var column = dataGrid.Columns.FirstOrDefault(c => c.Header.ToString() == header);    if (column != null)    {        column.Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed;    }}

2. 高级列类型

private DataGridTemplateColumn CreateProgressColumn(){    DataGridTemplateColumn column = new DataGridTemplateColumn();    column.Header = "完成进度";
    // 单元格模板    FrameworkElementFactory progressFactory = new FrameworkElementFactory(typeof(ProgressBar));    progressFactory.SetValue(ProgressBar.ValueProperty, new Binding("Progress"));    progressFactory.SetValue(ProgressBar.MinimumProperty, 0);    progressFactory.SetValue(ProgressBar.MaximumProperty, 100);    progressFactory.SetValue(ProgressBar.HeightProperty, 20.0);
    DataTemplate cellTemplate = new DataTemplate();    cellTemplate.VisualTree = progressFactory;    column.CellTemplate = cellTemplate;
    return column;}private DataGridTemplateColumn CreateRatingColumn(){    DataGridTemplateColumn column = new DataGridTemplateColumn();    column.Header = "评分";
    // 使用ItemsControl创建星级显示    FrameworkElementFactory stackFactory = new FrameworkElementFactory(typeof(StackPanel));    stackFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
    FrameworkElementFactory itemsFactory = new FrameworkElementFactory(typeof(ItemsControl));    itemsFactory.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("RatingStars"));
    DataTemplate starTemplate = new DataTemplate();    FrameworkElementFactory starFactory = new FrameworkElementFactory(typeof(TextBlock));    starFactory.SetValue(TextBlock.TextProperty, "★");    starFactory.SetValue(TextBlock.ForegroundProperty, Brushes.Gold);    starTemplate.VisualTree = starFactory;
    itemsFactory.SetValue(ItemsControl.ItemTemplateProperty, starTemplate);    stackFactory.AppendChild(itemsFactory);
    DataTemplate cellTemplate = new DataTemplate();    cellTemplate.VisualTree = stackFactory;    column.CellTemplate = cellTemplate;
    return column;}
三、行功能增强

1. 行样式和模板

<!-- 行详细信息模板 --><DataGrid.RowDetailsTemplate>    <DataTemplate>        <Border Background="#FFF0F0F0" Padding="10" Margin="5">            <StackPanel>                <TextBlock Text="{Binding Description}" TextWrapping="Wrap"/>                <StackPanel Orientation="Horizontal" Margin="0,5,0,0">                    <TextBlock Text="创建时间:" FontWeight="Bold"/>                    <TextBlock Text="{Binding CreateTime, StringFormat=yyyy-MM-dd}" Margin="5,0,0,0"/>                </StackPanel>            </StackPanel>        </Border>    </DataTemplate></DataGrid.RowDetailsTemplate><!-- 行样式 --><DataGrid.RowStyle>    <Style TargetType="DataGridRow">        <Setter Property="Background" Value="White"/>        <Setter Property="Height" Value="35"/>
        <Style.Triggers>            <!-- 鼠标悬停效果 -->            <Trigger Property="IsMouseOver" Value="True">                <Setter Property="Background" Value="#FFE3F2FD"/>            </Trigger>
            <!-- 选择行效果 -->            <Trigger Property="IsSelected" Value="True">                <Setter Property="Background" Value="#FF2196F3"/>                <Setter Property="Foreground" Value="White"/>            </Trigger>
            <!-- 行状态样式 -->            <DataTrigger Binding="{Binding Status}" Value="Inactive">                <Setter Property="Background" Value="#FFFFCDD2"/>                <Setter Property="Foreground" Value="#FFB71C1C"/>            </DataTrigger>
            <DataTrigger Binding="{Binding Status}" Value="Completed">                <Setter Property="Background" Value="#FFC8E6C9"/>                <Setter Property="Foreground" Value="#FF1B5E20"/>            </DataTrigger>        </Style.Triggers>    </Style></DataGrid.RowStyle>

2. 行号显示

// 添加行号列private void AddRowNumberColumn(){    DataGridTemplateColumn rowNumberColumn = new DataGridTemplateColumn();    rowNumberColumn.Header = "#";    rowNumberColumn.Width = new DataGridLength(40);
    // 创建单元格模板    FrameworkElementFactory textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));    textBlockFactory.SetBinding(TextBlock.TextProperty,         new Binding(".")         {             RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridRow), 1),            Converter = new RowNumberConverter()        });    textBlockFactory.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Center);    textBlockFactory.SetValue(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center);
    DataTemplate cellTemplate = new DataTemplate();    cellTemplate.VisualTree = textBlockFactory;    rowNumberColumn.CellTemplate = cellTemplate;
    dataGrid.Columns.Insert(0, rowNumberColumn);}// 行号转换器public class RowNumberConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        DataGridRow row = value as DataGridRow;        if (row != null)            return row.GetIndex() + 1;        return null;    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)    {        throw new NotImplementedException();    }}
四、排序和过滤
// 自定义排序public class CustomSorter{    public static void ApplySort(DataGrid dataGrid, string propertyName, ListSortDirection direction)    {        ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);        view.SortDescriptions.Clear();        view.SortDescriptions.Add(new SortDescription(propertyName, direction));    }
    // 多列排序    public static void ApplyMultiSort(DataGrid dataGrid, params (string Property, ListSortDirection Direction)[] sorts)    {        ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);        view.SortDescriptions.Clear();
        foreach (var sort in sorts)        {            view.SortDescriptions.Add(new SortDescription(sort.Property, sort.Direction));        }    }}// 使用示例private void SortByNameAscending(){    CustomSorter.ApplySort(dataGrid, "Name", ListSortDirection.Ascending);}private void SortByMultipleColumns(){    CustomSorter.ApplyMultiSort(dataGrid,        ("Department", ListSortDirection.Ascending),        ("Salary", ListSortDirection.Descending)    );}

2. 实时过滤

// 过滤管理器public class DataGridFilter{    private string _filterText = "";    private Predicate<object> _filterPredicate;
    public void ApplyFilter(DataGrid dataGrid, string filterText, string[] searchProperties)    {        _filterText = filterText?.ToLower() ?? "";
        if (string.IsNullOrEmpty(_filterText))        {            _filterPredicate = null;        }        else        {            _filterPredicate = item => SearchInItem(item, searchProperties);        }
        ICollectionView view = CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);        view.Filter = _filterPredicate;    }
    private bool SearchInItem(object item, string[] properties)    {        foreach (var property in properties)        {            var propInfo = item.GetType().GetProperty(property);            if (propInfo != null)            {                var value = propInfo.GetValue(item)?.ToString().ToLower();                if (value != null && value.Contains(_filterText))                    return true;            }        }        return false;    }}// 使用示例private void SetupFiltering(){    var filter = new DataGridFilter();
    // 设置搜索框文本变化事件    searchTextBox.TextChanged += (s, e) =>    {        filter.ApplyFilter(dataGrid, searchTextBox.Text, new[] { "Name", "Department", "Email" });    };}
五、分页功能
public class PaginationManager<T>{    private readonly ObservableCollection<T> _allItems;    private readonly int _pageSize;    private int _currentPage = 1;
    public ObservableCollection<T> CurrentPageItems { get; } = new ObservableCollection<T>();    public int TotalPages => (int)Math.Ceiling((double)_allItems.Count / _pageSize);    public int CurrentPage => _currentPage;
    public PaginationManager(ObservableCollection<T> allItems, int pageSize = 20)    {        _allItems = allItems;        _pageSize = pageSize;        UpdateCurrentPage();    }
    public void GoToPage(int pageNumber)    {        if (pageNumber >= 1 && pageNumber <= TotalPages)        {            _currentPage = pageNumber;            UpdateCurrentPage();        }    }
    public void NextPage()    {        if (_currentPage < TotalPages)        {            _currentPage++;            UpdateCurrentPage();        }    }
    public void PreviousPage()    {        if (_currentPage > 1)        {            _currentPage--;            UpdateCurrentPage();        }    }
    private void UpdateCurrentPage()    {        CurrentPageItems.Clear();
        var startIndex = (_currentPage - 1) * _pageSize;        var endIndex = Math.Min(startIndex + _pageSize, _allItems.Count);
        for (int i = startIndex; i < endIndex; i++)        {            CurrentPageItems.Add(_allItems[i]);        }
        OnPageChanged?.Invoke(this, EventArgs.Empty);    }
    public event EventHandler OnPageChanged;}// 在DataGrid中使用分页private PaginationManager<Employee> _paginationManager;private void SetupPagination(){    _paginationManager = new PaginationManager<Employee>(Employees, 15);    dataGrid.ItemsSource = _paginationManager.CurrentPageItems;
    // 更新分页信息显示    _paginationManager.OnPageChanged += (s, e) =>    {        UpdatePaginationInfo();    };
    UpdatePaginationInfo();}private void UpdatePaginationInfo(){    pageInfoText.Text = $"第 {_paginationManager.CurrentPage} 页,共 {_paginationManager.TotalPages} 页";    prevButton.IsEnabled = _paginationManager.CurrentPage > 1;    nextButton.IsEnabled = _paginationManager.CurrentPage < _paginationManager.TotalPages;}

通过这些高级技巧,你的DataGrid将具备:
✅ 强大的数据管理:实时更新、分页、过滤、排序
✅ 丰富的交互功能:多选、编辑、验证、导出
✅ 优秀的用户体验:虚拟化、主题切换、自定义样式
✅ 专业的视觉效果:行样式、单元格模板、动画效果

由于篇幅过长以上内容分为两篇哦敬请期待下一篇DataGrid进阶用法,有问题欢迎在评论区讨论哦!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐