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

如何根据数据类型设置WPF DataGrid单元格样式以显示Bitmap

解决WPF DataGrid根据单元格数据类型切换显示控件的问题

核心问题分析

你遇到的问题根源在于:AutoGenerateColumns默认会为所有列生成DataGridTextColumn,这类列会将所有数据转为字符串显示。即使修改CellStyle,如果没有针对不同数据类型指定对应的显示模板,Bitmap等非字符串类型依然无法正确渲染。

解决方案步骤

我们可以通过为DataGridCell设置ContentTemplate,结合数据类型匹配的DataTemplate,实现不同数据类型自动切换显示控件。同时需要一个转换器将System.Drawing.Bitmap转为WPF的ImageSource。

1. 编写Bitmap转ImageSource转换器

在代码后台添加以下转换器类,用于将WinForms的Bitmap转换为WPF可识别的ImageSource:

using System;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace YourNamespace
{
    public class BitmapToImageSourceConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is Bitmap bitmap)
            {
                var hBitmap = bitmap.GetHbitmap();
                try
                {
                    return Imaging.CreateBitmapSourceFromHBitmap(
                        hBitmap,
                        IntPtr.Zero,
                        Int32Rect.Empty,
                        BitmapSizeOptions.FromEmptyOptions());
                }
                finally
                {
                    DeleteObject(hBitmap);
                }
            }
            return DependencyProperty.UnsetValue;
        }

        [DllImport("gdi32.dll")]
        private static extern bool DeleteObject(IntPtr hObject);

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

2. 修改DataGrid的XAML代码

更新DataGrid的Style,重点修改CellStyle,为单元格内容添加类型匹配的DataTemplate:

<Window.Resources>
    <local:BitmapToImageSourceConverter x:Key="BitmapToImageSourceConverter"/>
</Window.Resources>

<DataGrid>
    <DataGrid.Style>
        <Style TargetType="DataGrid">
            <Setter Property="AlternationCount" Value="2"/>
            <Setter Property="AutoGenerateColumns" Value="True"/>
            <Setter Property="CellStyle">
                <Setter.Value>
                    <Style TargetType="DataGridCell">
                        <!-- 设置单元格内容模板,根据数据类型切换控件 -->
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <ContentControl Content="{Binding}">
                                        <ContentControl.Resources>
                                            <!-- Bitmap类型显示Image控件 -->
                                            <DataTemplate DataType="{x:Type Drawing:Bitmap}">
                                                <Image Source="{Binding Converter={StaticResource BitmapToImageSourceConverter}}"
                                                       Stretch="Uniform" MaxHeight="50" MaxWidth="100"/>
                                            </DataTemplate>
                                            <!-- 字符串类型显示TextBlock -->
                                            <DataTemplate DataType="{x:Type sys:String}">
                                                <TextBlock Text="{Binding}" VerticalAlignment="Center"/>
                                            </DataTemplate>
                                            <!-- 可扩展其他数据类型的模板,比如数字、日期等 -->
                                        </ContentControl.Resources>
                                    </ContentControl>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Background" Value="Transparent"/>
                        <Style.Triggers>
                            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                <Setter Property="Background" Value="#e0e0e0"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Setter.Value>
            </Setter>
            <Setter Property="HeadersVisibility" Value="Column"/>
            <Setter Property="IsReadOnly" Value="True"/>
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=DataContext.Data}"/>
        </Style>
    </DataGrid.Style>
</DataGrid>

注意:需要在XAML根节点添加以下命名空间引用:

xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:Drawing="clr-namespace:System.Drawing;assembly=System.Drawing"
xmlns:local="clr-namespace:YourNamespace"

关键说明

  • 不再重写DataGridCell的Template,而是通过ContentTemplate控制内容渲染,避免破坏默认的单元格布局逻辑。
  • 使用ContentControl加载内容,并通过资源中的DataTemplate自动匹配数据类型,无需手动判断。
  • 转换器必须正确释放GDI资源(调用DeleteObject),避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 15:40:06