Styling Microsoft’s WPF datagrid

DevCAI SimpleButton / CheckButton 按钮实现分析 分析对象:DevCAI 自研的与(对应第 2.3 节“选项、按钮与状态”中同名组件)(2286 行,单文件承载整个按钮家族)分析日期:2026-11-05技术栈:VS2022 / .NET Framework 4.8.1 / C# 8.0(库代码语法不高于 C# 7.3) 阅读详情

Styling Microsoft’s WPF datagrid

Microsoft’s WPF datagrid has a lot of properties and styles you can tweak to get it looking right (if you are a designer).  
Below, find my cheat sheet to styling the grid.   It is not 100% comprehensive but it gets you far and has a few very useful tips & gotchas. 

At the highest level in the DataGrid , you can change the look & feel by setting some of these:

PropertyTypeValuesDefault
AlternatingRowBackgroundBrushAny BrushNull
BackgroundBrushAny BrushTheme default
ColumnHeaderHeightDouble0 to any positive doubleNaN
ColumnHeaderStyleStyleAny StyleNull
ColumnWidthDataGridLength0 to any positive double, Auto, *, SizeToCells, SizeToHeaderSizeToHeader
HeadersVisibilityDataGridHeadersVisibilityAll, Row, Column, NoneAll
MaxColumnWidthDouble0 to any positive doublePositive Infinity
MaxRowHeightDouble0 to any positive doublePositive Infinity
MinColumnWidthDouble0 to any positive double20
MinRowHeightDouble0 to any positive double0
RowBackgroundBrushAny BrushTheme default
RowDetailsVisibilityModeDataGridRowDetailsVisibilityModeVisible, VisibleWhenSelected, CollapsedVisibleWhenSelected
RowHeadersWidthDouble0 to any positive doubleNaN
RowHeightDouble0 to any positive doubleNaN
AlternationCountint2+coerced to 2
GridLinesVisibilityDataGridGridLinesVisibilityAll, Horizontal, Vertical, NoneAll
HorizontalGridLinesBrushBrushAny BrushBlack(via metadata)
VerticalGridLinesBrushBrushAny BrushBlack(via metadata)
ItemTemplateDataTemplateAny DataTemplateNull
RowDetailsTemplateDataTemplateAny DataTemplateNull
CellStyleStyleAny StyleNull
ItemContainerStyleStyleAny StyleNull
RowHeaderStyleStyleAny StyleNull
RowStyleStyleAny StyleNull
StyleStyleAny StyleNull
TemplateControlTemplateControlTemplate TargetType=DatagridNull

 

 

Here, you can see a visual representation for a few of these properties (the visual is not all inclusive); this will give you an idea of what this article will cover.

DataGridVisually2

 

Backgrounds: 
The interesting part are the relationships amongst the backgrounds:

  • Background – sets the whole data grid’s background.  Notice it can be any brush, solid and gradients is obvious, but why not a DrawingBrush like the bear above ( which you can see if you squint hard, it has Opacity =0.1) 
  • RowBackground  and AlternatingRowBackground  set the background for a row and alternating row.  
    Both of these have a higher z-order than DataGrid’s background of course, which means you can get visual composition w/ the grid’s background.  
    Notice that the default color for RowBackground is theme based (and default value is opaque); your DataGrid’s background will not be visible unless you override these row backgrounds to be partially transparent. 
  • AlternationCount is the total number of styles or colors that will be used for the rows.  This number is one-index based (meaning count starts at 1, not 0).
    • If you set AlternationCount > 2, your rows from 3rd row to AlternationCount will be assigned the default background brush value (from the theme).
    • The way to set the different backgrounds or styles for each row based on AlternationCount is by overriding the style for your DataGridRow and triggering based on AlternationIndex, which is actually zero-index based.  
    • If you set the AlternatingRowBackground brush, it will be assigned to the rows where the ( rownumber%AlternationIdex ) == 1 

Here is an example of overriding RowStyle to tweak background based on AlternationIndex:

 <Style x:Key="DataGridDemoRowStyle"  
       TargetType="{x:Type Custom:DataGridRow}">
    <Style.Triggers>
        <Trigger Property="AlternationIndex" Value="2" >
            <Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex2Brush}" />
        </Trigger>
        <Trigger Property="AlternationIndex" Value="3">
            <Setter Property="Background" Value="{StaticResource RowBackgroundAlternationIndex3Brush}" />
        </Trigger>
    </Style.Triggers>
</Style> 

Notice that, on purpose, I only override AlternationIndex = 2,3.  For AlternationIndex=0, it uses RowBackground. 
For AlternationIndex = 1, it uses AlternatingRowBackground from the datagrid.  
 

 

Datagrid Column Headers

I usually customize the header on a data grid to accomplish one of two tasks:

  • Tweak the background of the headers, including triggers for hovers, selected, etc.
  • Tweak the Control template of the header, mostly because the default style to show Sorting is on top of ColumnHeader and I like it on the side.

My instinct was that customizing the header’s background would be a simple style override. Here is my try:

<Style x:Key="DataGridColumnHeaderStyle" TargetType="{x:Type Custom:DataGridColumnHeader}"  >
    <Setter Property="Background" Value="#88800080" />
        <Setter Property="Foreground" Value="White" /> 
        <Style.Triggers>
        <Trigger Property="SortDirection" Value="{x:Null}">
            <Setter Property="Background" Value="{DynamicResource DataGridHeaderBackgroundBrush}" />
            <Setter Property="BorderBrush"  Value="Transparent" />
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver" Value="True" />
                <Condition Property="SortDirection" Value="{x:Null}" />
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
            <Setter Property="BorderBrush" Value="{StaticResource DataGridHeaderBorderBrush}" />
        </MultiTrigger>

        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver" Value="true" />
                <Condition Property="SortDirection" Value="{x:Null}" />
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
            <Setter Property="BorderBrush" Value="{StaticResource DataGridHeaderBorderBrush}" />
        </MultiTrigger>
        <Trigger Property="SortDirection" Value="Ascending">
            <Setter Property="Background" Value="{StaticResource DataGridHeaderSortedBackgroundBrush}" />
        </Trigger>
        <Trigger Property="SortDirection" Value="Descending">
            <Setter Property="Background" Value="{StaticResource DataGridHeaderSortedBackgroundBrush}" />
        </Trigger>
    </Style.Triggers>
</Style>

If you run the sample code against that style, you will notice that the Sort direction arrow that is shown in the default style for the Datagrid disappeared'; the reason for it is that DataGridColumnHeader uses DataGridHeaderBorder in its template;  DataGridHeaderBorder is a kind of smart Border that checks if you set a Background and if you did, it behaves like a Border; if you did not set a Background, it then acts smartly and does the code to render the triangle indicator for sort. 

If you do want sort direction arrows, and a different background you should just override the template and use a regular Border or what ever you want for the background.  Overriding the template is not too hard, here is an example:

<Style x:Key="DatagridColumnHeaderCustomTemplateStyle" 
         TargetType="{x:Type Custom:DataGridColumnHeader}">
      <Setter Property="SnapsToDevicePixels" Value="True" />
      <Setter Property="MinWidth" Value="0" />
      <Setter Property="MinHeight" Value="28" />
      <Setter Property="Foreground" Value="White" />
      <Setter Property="Cursor" Value="Hand" />
      <Setter Property="Template">
          <Setter.Value>
              <ControlTemplate TargetType="{x:Type Custom:DataGridColumnHeader}">
                  <Grid>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition Width="*" />
                          <ColumnDefinition Width="Auto" />
                      </Grid.ColumnDefinitions>
                      <Border x:Name="BackgroundBorder" BorderThickness="0,1,0,1" 
                              Background="{StaticResource DataGridHeaderSortedBackgroundBrush}" 
                              BorderBrush="{StaticResource DataGridHeaderSortedBorderBrush}" 
                              Grid.ColumnSpan="2" />
                      <ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center" />
                      <Path x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" 
                            Grid.Column="1" Width="8" Height="6" Fill="White" Margin="0,0,8,0" 
                            VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" />
                      <Rectangle Width="1" Fill="#AAC377" HorizontalAlignment="Right" Grid.ColumnSpan="2" />

                      <Rectangle Width="1" Margin="0,0,1,0" Fill="#425B10" 
                                 HorizontalAlignment="Right" Grid.ColumnSpan="2" />
                      <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" 
                             Style="{StaticResource ColumnHeaderGripperStyle}"/>
                      <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" 
                             Style="{StaticResource ColumnHeaderGripperStyle}"/>
                  </Grid>
                  <ControlTemplate.Triggers>
                      <Trigger Property="SortDirection" Value="{x:Null}">
                          <Setter TargetName="BackgroundBorder" Property="Background" 
                                  Value="{DynamicResource DataGridHeaderBackgroundBrush}" />
                          <Setter TargetName="BackgroundBorder" Property="BorderBrush"  
                                  Value="Transparent" />
                      </Trigger>
                      <MultiTrigger>
                          <MultiTrigger.Conditions>
                              <Condition Property="IsMouseOver" Value="True" />
                              <Condition Property="SortDirection" Value="{x:Null}" />
                          </MultiTrigger.Conditions>
                          <Setter Property="Background" TargetName="BackgroundBorder" 
                                  Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
                          <Setter Property="BorderBrush" TargetName="BackgroundBorder" 
                                  Value="{StaticResource DataGridHeaderBorderBrush}" />
                      </MultiTrigger>
                      <MultiTrigger>
                          <MultiTrigger.Conditions>
                              <Condition Property="IsMouseOver" Value="true" />
                              <Condition Property="SortDirection" Value="{x:Null}" />
                          </MultiTrigger.Conditions>
                          <Setter TargetName="BackgroundBorder" Property="Background" 
                                  Value="{StaticResource DataGridHeaderMouseOverBackgroundBrush}" />
                          <Setter TargetName="BackgroundBorder" Property="BorderBrush" 
                                  Value="{StaticResource DataGridHeaderBorderBrush}" />
                      </MultiTrigger>

                      <Trigger Property="SortDirection" Value="Ascending">
                          <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                          <Setter TargetName="SortArrow" Property="RenderTransform">
                              <Setter.Value>
                                  <RotateTransform Angle="180" />
                              </Setter.Value>
                          </Setter>
                      </Trigger>
                      <Trigger Property="SortDirection" Value="Descending">
                          <Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
                      </Trigger>
                      <Trigger Property="DisplayIndex" Value="0">
                          <Setter Property="Visibility" Value="Collapsed" 
                                  TargetName="PART_LeftHeaderGripper"></Setter>
                      </Trigger>
                  </ControlTemplate.Triggers>
              </ControlTemplate>
          </Setter.Value>
      </Setter>
  </Style>

A few things to notice above:  I replaced DataGridHeaderBorder for a normal border; I added a little “triangle” for sort direction, and then transform it (or flip it) based on SortDirection.

 

DataGrid Row Headers

For me, these are the most common ‘tweaks’ to RowHeader.

  • Tweaking the width (as the default is too small)
  • Tweaking the background to match my theme.
  • Implementing row selection by clicking on the row header; this feature does not come out of the box.
  • Error handling happens in the RowHeader

My very first try when looking at the API was to set Row Header Width via styles.  Later on, I realized that DataGrid exposed the RowHeaderWidth property directly so I am now using that instead.  This is a trivial property setter. 

For tweaking  the background,  I first tried setting a the RowHeader style property in the datagrid. The basic style I tried looked like this: 

 <Style x:Key="DataGridRowHeaderBackgroundStyle" TargetType="{x:Type Custom:DataGridRowHeader}">
        <Setter Property="Background" Value="Gray" />
    </Style>

 

It works, but similar to ColumnHeaders I lost functionality.  At run-time, it looked like this:

RowHeaderBackgroundOnly

As you will notice, it lost the row DataGridLines that separates each row; there are no hovers, etc.  
I then proceeded to override the template.  The change was actually trivial, I noticed that DataGridHeaderBorder defaults back to the rendering for it’s base class (Border),  so this mostly implied setting a BorderThickness on it to fake the grid’s row separators, and binding the color to the DataGrid’s HorizontalGridLinesBrush.. 

Here is the template that I created for the DataGridRowHeader.. (and below the explanation on a few extra gotchas).

<Stylex:Key="{x:TypeCustom:DataGridRowHeader}"TargetType="{x:TypeCustom:DataGridRowHeader}"> 
    <
SetterProperty="Background"Value="{StaticResource RowHeaderBackgroundBrush}" />      
    <
SetterProperty="Template"> 
        <
Setter.Value> 
            <
ControlTemplate TargetType="{x:TypeCustom:DataGridRowHeader}"> 
                <
Grid>                        
                    <
Custom:DataGridHeaderBorder IsSelected="{TemplateBinding IsRowSelected}" 
                                 
IsHovered ="{TemplateBinding IsMouseOver}" 
                                 
IsPressed="{TemplateBinding IsPressed}" 
                                 
BorderBrush="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGrid}}, 
                                    
Path=HorizontalGridLinesBrush}" 
                                 
Background="{TemplateBinding Background}"                                     
                                 
BorderThickness="0,1,0,0" 
                                 
Padding ="{TemplateBinding Padding}" 
                                 
Orientation="Horizontal" 
                                 
SeparatorVisibility="{TemplateBinding SeparatorVisibility}" 
                                 
SeparatorBrush="{TemplateBinding SeparatorBrush}" Margin="0,-1,0,0"> 

                        <
StackPanel Orientation="Horizontal"> 
                            <
ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                              
VerticalAlignment="Center"/> 
                            <
Control SnapsToDevicePixels="false" 
                       
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
                                
Path=(Validation.HasError), 
                       
Converter={StaticResource bool2VisibilityConverter}}" 
                       
Template="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
                                
Path=ValidationErrorTemplate}" /> 
                        </
StackPanel> 
                    </
Custom:DataGridHeaderBorder> 
                    <
Thumb x:Name="PART_TopHeaderGripper" 
               
VerticalAlignment="Top" Height="3" 
               
Style="{StaticResource RowHeaderGripperStyle}"/> 
                    <
Thumb x:Name="PART_BottomHeaderGripper" 
               
VerticalAlignment="Bottom" Height="3" 
               
Style="{StaticResource RowHeaderGripperStyle}"/> 
                </
Grid> 

                <
ControlTemplate.Triggers>                        
                    <
Trigger Property="IsMouseOver" Value="True"> 
                        <
Setter Property="Background" Value="{StaticResource RowHeaderIsMouseOverBrush}" /> 
                    </
Trigger> 
                    <
Trigger Property="IsRowSelected" Value="True"> 
                        <
Setter Property="Background" Value="{StaticResource RowBackgroundSelectedBrush}" /> 
                    </
Trigger> 
                </
ControlTemplate.Triggers> 
            </
ControlTemplate> 
        </
Setter.Value> 
    </
Setter> 
</
Style>

 

The interesting changes were:

  • I had to use an implicit style.  Though the DataGrid does have have RowHeaderStyle property, it some how did not work for me; which is weird because RowHeaderStyle worked fine when I used style that did not override the template. 
  • The BorderThickness of DataGridHeaderBorder is set to 0,1,0,0..  and that makes it draw the equivalent of a GridLine,  I offseted the Margin by 0,-1,0,0  to make sure this aligned with the DataGridRow GridLines. 
  • BorderBrush in DataGridHeaderBorder is bound to the DataGrid’s HorizontalGridLinesBrush. 
  • I went ahead and added a trigger for IsRowSelected, bound to a local Brush in the dictionary. So now the RowHeader will display its Selected state visually. 
  • I added a trigger for IsMouseOver,   it is just ‘expected behavior’. 
  • I set a Height of Size 3 to the Thumbs used for the grippers that resize the row. The reason I did this is because I like to be able to double click on a header and have it select the whole Row; this functionality is implemented in the datagrid,  but the Thumbs are so big that they get on the way of trying to click in the RowHeader.  A size of 2 or 3 for the Thumbs seems to do fine for dragging and leaves enough room for clicking on the RowHeader to select row. 
  • Another interesting feature I learned when playing with RowHeader was that if you double  click in the Thumbs that resize the row, it goes back to its original size.  Nice touch (that I did not know about).

Moving on to the task of reporting errors in the RowHeader,  I did not tweak the DataGridRowHeader at all to do any thing related to errors.  I did it all via the DataGrid’s ErrorTemplate property to point to ErrorTemplate2 in my resource dictionary.

<ControlTemplate x:Key="ErrorTemplate2">
       <Grid  MinWidth="20" MinHeight="20">
            <Rectangle Fill="{StaticResource ErrorTemplateBrush}" />      
       </Grid> 
</ControlTemplate>

 

<digression> 
I do not like that ErrorTemplate is a ControlTemplate. In my opinion it should be a DataTemplate with access to the DatagridRow’s context and the DatagridRow’s error collection.   As a ‘workaround you can try to pass this into the control yourself by tweaking the  RowHeaderTemplate, and passing the DataContext into the control that acts as placeholder for ErrorTemplate, like this:

<Control SnapsToDevicePixels="false"
Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
        Path=(Validation.HasError), 
Converter={StaticResource bool2VisibilityConverter}}"
Template="{Binding RelativeSource={RelativeSource AncestorType={x:Type Custom:DataGridRow}}, 
        Path=ValidationErrorTemplate}" 
                 DataContext="{Binding
                    RelativeSource={RelativeSource  AncestorType={x:Type Custom:DataGridRow}},
                    Path=(Validation.Errors)[0].ErrorContent }"                                             
                    >

You can then tweak the ErrorTemplate datagrid with a tooltip:

<ControlTemplate x:Key="ErrorTemplate2">
      <Grid  MinWidth="20" MinHeight="20" ToolTip="{Binding}">
           <Rectangle Fill="{StaticResource ErrorTemplateBrush}" >               
           </Rectangle>             
       </Grid> 
</ControlTemplate>

and get something more helpful error message, like this:

ToolTipError

</digression>

 

Cell Styles

By default the DataGrid’s cell show a themed, blue background when selected (see image in closing thoughts below), I did not like that, so I used DataGrid’s CellStyle to take care of that. Override the default template and remove the triggers for selection:

<Style x:Key="DataGridCellStyle" TargetType="{x:Type Custom:DataGridCell}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Custom:DataGridCell}">
                    <Border Background="Transparent" 
                  BorderBrush="{TemplateBinding BorderBrush}"  
                  BorderThickness="0" 
                  SnapsToDevicePixels="True">
                        <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

 

RowDetailsTemplate

The RowDetails Template is displayed when a row is selected. It is a DataTemplate with the context of the row.  In this demo, the implementation is trivial, all I did was put a textblock, but you can do much more complex RowDetails on a real project.

<DataTemplate x:Key="RowDetailsTemplate"> 
        <Grid TextBlock.Foreground="White"> 
            <Grid.RowDefinitions>
                <RowDefinition /> 
                <RowDefinition />                 
            </Grid.RowDefinitions>
            <TextBlock Text="RowDetails Go here"  Grid.Row="0"/>             
            <TextBlock Text="{Binding }" Grid.Row="1"/> 
        </Grid>
        
</DataTemplate>

The main reason to mention RowDetailsTemplate is to emphasize the ‘synchronization’ that needs to happen when a row is selected:  RowDetailsTemplate, RowBackground, and RowHeader’s background should  all align to make sure their backgrounds are color coordinated.   In this case, if you look at the templates above, I did make sure they matched for selection and set the background to the ‘dark blue’ gradient.


Closing Thoughts: 
This writing is not all inclusive; there is lots more you can do to style the datagrid.  
I do have to say, it is neat that in the usual “WPF designer friendly” mark-up tweaks, we went from a plain grid (see left) to a styled grid ( see right) with out writing a single line of code.  

CheesyDataGridSummary

 

What now? 
To compliment this styling tutorial, I recommend Colin Eberhardt’s “WPF Datagrid Practical Examples” article. He does a great job at sharing insights into data binding, validating and even styling the datagrid. Thanks Colin!

  
The source code for this writing is here.   Thanks for reading this

WpfDataGridStyle 这个表格样式是网上的开源资源 给了我很大的启发 上传上来大家共享 是个好资源! 立即下载

相关推荐

第4课 SiC MOSFET的动态特性——关断过程

本文分析了SiC MOSFET的关断过程,将其划分为四个阶段:栅源电容放电阶段(t6-t7)、米勒平台阶段(t7-t8)、电压过冲阶段(t8-t9)和换流结束阶段(t9-t10)。通过等效电路详细描述了各阶段的电压电流变化特点。同时探讨了MOSFET的极间电容特性,包括输入电容Ciss、输出电容Coss和反向转移电容Crss,分析了它们对器件开关速度、损耗及电压变化速率的影响。研究指出这些非线性电容会显著影响器件的动态性能。

嵌入式老牛的博客 1045

WPF之DataGrid用法(一)

介绍数据表格DataGrid的基础用法。 DataGrid可用AutoGenerateColumns属性控制列的生成。Column包含DataGridTextColumn、DataGridCheckBoxColumn、DataGridComboBoxColumn、DataGridHyperlinkColumn、DataGridTemplateColumn等5中格式。 1.DataGri

FoolRabbit的专栏 3万+

数据结构与算法 —— 最短路径Dijkstra算法(迪杰斯特拉)详细图解以及python实现

前两章我们讲到了关于图的基本知识,和广度/深度优先搜索。本章,我们将介绍加权图和最短路径的相关知识。最短路径和最小生成树是图论中常见的问题。最短路径是指在一个图中找到两个节点之间的最短路径,最小生成树是指在一个图中找到一个连通子图,使得所有节点都能够互相到达,且总权值最小。最短路径算法常见的有floyd算法(弗洛伊德算法)和 dijkstra算法(迪杰斯特拉)。本文只介绍dijkstra算法。最短路径运用非常广泛,比如在导航系统中,确定两个地点间哪条路线最短;

‘’ 2万+

ControlTemplate in WPF —— DataGrid

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style TargetType="{x:Type B

Leo‘s Blog 3294

树莓派4B:控制步进电机

文章目录准备阶段接线阶段树莓派程序 准备阶段 准备以下物品,淘宝都可以买到: 57步进电机 电源开关(220v转24v,3A,72W) 步进电机驱动器 电源线 电线 杜邦线 树莓派4B一套 具体型号如下: 接线阶段 整体:接线效果如下图 电源开关起220v转24v作用,很好接线,输出24v接入步进电机驱动器 步进电机驱动器的 A+ A- B+ B- 按提示接步进电机四线,步进电机上就会有说...

学习路上的鸭子的博客 1万+

手把手教你用OpenClaw+飞书打造论文写作AI助手(附踩坑实录)

面对几十篇文献,逐一阅读摘要都费时。我:“请提取桌面‘论文参考文献’文件夹中所有PDF的摘要,整理成表格,包含:论文标题、作者、发表年份、核心方法、主要结论。AI助手:“正在处理...已提取18篇论文摘要,汇总表格已保存到桌面‘文献摘要汇总.xlsx’。这比我自己一个个打开PDF复制粘贴快了不止100倍。OpenClaw+飞书的组合,让AI真正成为了我的“数字员工”。虽然配置过程有些曲折,但看到它在飞书里回应指令、帮我处理繁琐工作时,那种成就感无可替代。如果你也在准备论文,不妨试试这套方案。记住,

AcademicIdeas的博客 1041

WPF DataGrid 样式分享

隔行换色,鼠标单击,悬浮样式都有 先看效果:

金石软件 3791

HTML5期末大作业:关于家乡介绍的HTML网页设计——郑州美景HTML+CSS(5页) 学生DW家乡介绍网页设计作业成品 web课程设计网页规划与设计

HTML5期末大作业:我的家乡——郑州美景HTML+CSS(5页) 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码 常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 明星、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他 等网页设计题目, A+水平作业, 可满足大学生网页大作业网页设计需求, 喜

qq_365392777 1万+

WPF: 定制datagrid, 让他更漂亮些 & WPF其他资料整理

前些日子, 我们准备, 为我们的打印机解决方案中增加一个新工具, 他是一个安装在Windows上的客户端程序. 我们的客户, 除了功能以外, 还提出了另外的一个要求, 就是希望这个新工具能长的漂亮些, 花哨些~   WPF在定制Style和Template方面, 比WinForm更有优势, 所以很自然的, 这次我们是用了WPF, 在这篇blog中, 我将整理一下当时调查的一些资料. ...

SAP => Simplify Anything Possible 1229

用Java和MQTT搞定大疆无人机自动巡检:一个真实机场项目的踩坑与优化记录

本文详细介绍了如何利用Java和MQTT协议实现大疆无人机在机场自动巡检系统的开发与优化。通过实战案例分享系统架构设计、通信协议选型、断线重连机制及数据通道优化等关键环节,帮助开发者解决GPS信号漂移、MQTT消息风暴等典型问题,提升系统性能和可靠性。

weixin_30275415的博客 495

2 中望CAD二次开发-绘制图形(ZRX C++)

本文讲解中望CAD二次开发,关于块的概念及基本图形的绘制

cilvsuanna的博客 411

微软技术日报 11-09:.NET 8 与 9 明日同时停止支持,注册表编辑器出了 WinUI 3 版

今天这四条消息的共同点是收口。.NET 8 和 9 的支持期到点,注册表编辑器的新界面只放在仓库里给人看,GitHub 把一类危险触发器按住默认,微软在安全报告里把防线从地址黑名单挪到行为。收口并不等于关门。.NET 10 还在支持期里,被按住的触发器可以用策略按文件放回来,实验室里的样例随时可能变成产品。区别在于这些动作要有人签字,不再是默认开着。如果今天只做一件事,去看一眼构建机上的 .NET 版本。明天之后,8 和 9 的漏洞补丁不会再来了。

海盗Sharp的博客 308

手把手教你学Simulink——基于Simulink的储能PCS(功率转换系统)离网V/f控制仿真示例

本文带你从零开始,在Simulink中硬核还原了一套完整的100kW 储能PCS离网V/f控制系统。通过引入:✅无PLL的自主角度生成机制(实现真正的“构网”能力)✅电压外环与电流内环的双闭环解耦架构(兼顾稳态精度与动态响应)✅黑启动软充电与有源阻尼等工程化手段(确保系统平滑建压与抗谐振)核心收获透彻理解了储能系统在无大电网支撑下的自主运行机理。掌握了从“跟网(Grid-Following)”向“构网(Grid-Forming)”跨越的控制算法核心差异。

MHD0815的博客 77

微软技术日报 2026-11-05:安装器变现链被拆开、OneLake 托管 MCP、Agent 365 进 Gartner 象限

把这几条放在一起看,共同点是把已经铺开的东西补上治理。安装器那条最直白。用户自己点开的程序,装完还会往回连,落地的东西藏在计划任务里、Program Files 里,用户不知道。微软给的检测思路也是往这个方向走的,看临时目录、看回调、看 SYSTEM 任务,而不是追域名。OneLake 那条是给 agent 补路标。以前每种 item 类型都要维护一份端点清单,现在让服务自己报出来。好处是 agent 不用猜,代价是判断责任转移到了客户端,技能要不要加载得自己决定,标签也不能当成授权。

海盗Sharp的博客 1384

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

设置ODBC的自定义类CSetODBC

何志丹一,功能描述用于配置数据源用户名及密码.1,可以得到连接串,此串可用于CMyRecordset(派生于CRecordset)的GetDefaultConnect(),也可以用干CDataBase类OpenEx.2,如果用户配置正确,只需要配置一次,相关信息记录在文件.3,可以指定存储信息的文件名.因为有可能几个程序共用一个数据源.4,用户可以重新配置数据5,可以得到当前数据的类型.6

闻缺陷则喜何志丹 3116

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

微软技术周报 11-02~11-09:VS Code 混装 Claude 与 Codex、EF Core 11 静默改行为、.NET 11 倒计时

11 月 6 日,Power Platform 通过消息中心通知管理员,Copilot Studio、Power Automate 和 Power Apps 里所有跑在 Anthropic Claude、xAI Grok 以及旧版 GPT 上的 prompt,12 月 2 日自动迁移到 GPT-6 系列,档位价格不变,模型选择收窄到一条产品线。效果是这样的:让 Claude 评审一个 Copilot chat 写出的方案,或者把同样的任务交给 Codex,两边并排跑在同一个会话里。更要紧的是下周的时间线。

海盗Sharp的博客 427

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

微软常用运行库合集免费下载安装教程(附运行库安装包)微软运行库安装图文教程

系统装完后出现“丢失xxx.dll”错误,多因缺少微软运行库所致。微软常用运行库合集将2005至2022年主流版本打包,一键安装,覆盖绝大多数软件依赖。无需判断版本,全选安装即可,装完建议重启。该合集可重复安装,不冲突,且与系统自带组件共存。适用于刚装系统的用户,能有效解决软件打不开、闪退等问题。

kk_net8899的博客 169

微软技术日报 11-08:Foundry 与 Entra 各挂一个 10.0 分漏洞,Foundry 接 fal 五款视频模型

这一周的动作可以分成两类。一类在收。Copilot 从电视上退场,搜索里的 AI 改成可选,云端漏洞只发通知不收补丁。共同点是承认铺得太开,代价比预期高。另一类在放。Foundry 一次摆上五个视频模型,容器版应用网关一个入口挂 64 个 MCP 服务器。共同点是把能力做成可组合的积木,让使用者按需挑。两个方向背后是同一个判断。把能力塞到每一个界面上,短期看覆盖率高,长期要解释为什么删不掉。新的做法是先给一个能关的开关,再谈覆盖。对每天写代码的人来说,今天有两样现成的东西可以试。

海盗Sharp的博客 368

【测评】SenseNova6.8Flash模型正式发布,支持动态 PPT 及 3D 设计

SenseNova 6.8 Flash将设计生成拓展至多种创作形态,支持Web、SVG、Three.js、Blender、PPT等形式,满足多样化的AI Native Design需求,并支持动态PPT、动态Poster与Agentic 3D设计。同时,模型可接入Figma等专业工作流,帮助用户将AI设计能力融入现有的专业设计流程。此外,模型还支持三维场景与交互内容创作,可综合处理空间布局、材质与光照、镜头控制及动画编排等因素,构建可在网页中实时渲染的三维内容,拓展从立体视觉展示到动态交互的表达方式。

Enweitech Software Works 321

微软推出 dotnetup:多版本管理更省心~

这是一个官方出品的.NET 工具链管理器,目前处于公共预览阶段,定位类似 Rust 生态中的 rustup。‌‌。

Enweitech Software Works 391

Qt窗口:对话框:模态、非模态、混合属性;内置对话框:消息、颜色、文件、字体、输入

对话框:模态exec、非模态show、混合属性setModal(true)+show;内置对话框:消息QMessageBox、颜色QColorDialog、文件QFileDialog、字体QFontDialog、输入QInputDialog

Wangshijie1015的博客 246

微软技术日报 2026-11-03:冒牌 Claude Code 扩展留后门、Fabric 数据工程 agent 进预览、Access IE 控件定退场

微软安全博客在 10 月 30 日复盘了一起扩展市场供应链事件:一个冒用 Anthropic 名字的 Cursor 扩展,在被下架之前挂了约 11 个小时。它做的事情不复杂,装完之后在你机器上开一条反向 SSH 隧道,留三处开机自启,再把主机信息发回一台固定 IP 的服务器。同一天前后,微软在 Fabric 社区大会巴塞罗那站把数据工程 agent(Project Osmos)放进了公共预览,在乌镇拿了一个奖,Access 团队则给一个用了二十年的浏览器控件定了退场日期。

海盗Sharp的博客 430

视频美颜sdk的API设计会影响开发效率吗?

视频美颜SDK不仅需要具备优秀的图像处理能力,API接口设计同样会影响软件开发效率。本文从接口调用、参数配置、版本兼容、开发文档以及业务扩展等多个角度,分析API设计对视频美颜SDK集成和后期维护的实际影响,为直播APP、视频社交平台等项目的SDK选型与技术开发提供参考。

wanyuekeji的博客 210

微软 BioEmu2 实测:AI 设计的抗体,能否通过动态模拟提前筛选?

微软 BioEmu2 实测:AI 设计的抗体,能否通过动态模拟提前筛选?**2026 年 10 月 26 日,展示了一个 AI 抗体候选的 10 纳秒传播动画。**但这个案例留下的最大问题,仍是实验室门前那道选择题:一批看起来合理的设计,究竟该把哪几个送去测试?Ford 正在参与 Adaptyv 与 Anthropic 的蛋白设计竞赛,也在开发抗体语言模型。**但他在原文中坦言,生成候选容易,挑出值得测试的候选依然困难。**本文解读他的公开实测,并对照微软文档核查证据边界,未独立运行模型。

weixin_71777199的博客 191

微软技术日报 2026-11-04:8GB 专属优化、38 万漏洞利用统计、NuGet 包带技能

11 月的第一周,微软把注意力放回了最不显眼的那批机器。11 月 3 日,Windows 官方博客发出一篇由 Pavan Davuluri 署名的文章。他是微软执行副总裁,负责 Windows 与设备。文章的题目直白得少见,讲的是怎么把 8GB 内存的 Windows 11 电脑拉到及格线以上。同一天,.NET 博客在讲另一件事,怎么把 agent skills 塞进 NuGet 包。11 月 2 日,微软安全研究发了一份跨 27 年的漏洞利用统计。

海盗Sharp的博客 453
上一篇: 混合编程关键词
下一篇: Styling hard-to-reach elements in control templates with attached behaviours
cool_time
博客等级 码龄19年 2粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值