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 这个表格样式是网上的开源资源 给了我很大的启发 上传上来大家共享 是个好资源! 立即下载

相关推荐

KNX实战—ETS5_智能开关从零到一的配置全流程

本文详细介绍了使用ETS5软件配置KNX智能开关的完整流程。从创建项目、构建建筑结构,到导入产品数据库、添加并配置开关模块与智能面板,再到设置延时开关、闪烁报警等进阶功能,并深入解析了群组地址的配置与链接方法。最后指导完成项目校验与程序下载,帮助用户实现从零到一的智能灯光基础控制功能配置。

joy55的博客 541

WPF之DataGrid用法(一)

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

FoolRabbit的专栏 3万+

IsaacLab从入门到精通(二) 导入自定义机器人

IsaacLab系列第二讲,导入自定义的机器人及设置

DejaWu33的博客 8466

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

【HAL库-STM】智能温控按键小风扇【胎教级教学】

硬件设备:DHT11,0.96寸oled屏,二/三/四线风扇(不挑),面包板 、f10的精英板等等。当人在的风扇面前时可以自行控制风扇,不在面前时又想开风扇就让他温控自行开启,(在这里有一个想法就是加上蓝牙和wifi控制的功能能够远程遥控,这个如果做的再全一点就要自主研发是一个多功能app,这里没有做。针对这个dht11,我一开始是卡在了这个check函数里面,一直是我给完dht11低电平和高电平后,dht11不回复我低电平和高电平,这个不是我的问题,当时代码是没毛病的,这个点一直卡着我。吐血五天实现小成品

weixin_52451652的博客 1740

Blender - Shrinkwrap - 更方便的制作贴合模型的表面来建模

Shrinkwrap 修改器 使用 Blender 想要快速建模可以贴合现有模型表面的效果:衣服、皮肤、等效果,可以使用 Shrinkwrap 修改器,这个修改器的名字其实按照英文上的理解,翻译为:收缩的包裹效果 应用 如这块铁皮,它要贴合机身弯曲的效果,可以先建好一个铁皮,再 Shrinkwrap 到一个指定的网格上 留意的参数 Target 要贴合的对象(目前我已知是可以贴合到网格对象上,实在是方便) VertexGroup 顶点组,和之前讲到过的,顶点组可以组设顶点的权重,意思这个可.

Jave.Lin 的学习笔记 6070

WPF DataGrid 样式分享

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

金石软件 3791

飞行器坐标转换

本文定义的是右手直角坐标系,x−y−zx-y-zx−y−z轴分别为北-天-东。从AAA坐标系到BBB坐标系是分别绕y−z−xy-z-xy−z−x轴,即天-东-北旋转ψ−θ−γψ−θ−γ。如果AAA是惯性系,BBB是机体系,则这三个角度分别为偏航角、俯仰角、横滚角。图1 惯性系到机体系。

gongfuyd的博客 1355

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

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

SAP => Simplify Anything Possible 1229

AI视频生成工作流开发:从产品拆解到带货视频全流程实现

本文介绍了一套完整的AI视频生成工作流开发方案,该系统能够自动分析产品素材并生成9个标准化分镜,支持白底图智能替换,最终输出专业带货视频。系统基于Coze平台搭建,整合豆包大模型及多模态生成模型,实现从产品分析、脚本生成到视频合成的全流程自动化。关键模块包括产品特征提取、智能分镜分配、视觉内容生成和用户交互调整,支持手动优化提示词和输出结果。该方案采用模块化设计,结合多种AI模型协同工作,为电商视频制作提供高效解决方案。

huanghm88的专栏 384

SPME/IP PPT详解

什么是中间件?它是操作系统与应用程序之间的一块代码,它对于应用程序提供了一些标准接口,屏蔽了应用程序与底层的一些交互,上层应用程序只要和中间件进行交互就可以了,这样就可以达到一个解耦的目的。SOMEIP其实是一个中间件,它是操作系统与应用程序之间的一段代码,它是可以运行在TCP/IP之上的,可以在很多平台上使用,可以适配较多的操作系统,可以提供很多接口。经过序列化之后,在网络上传输的是一些101010这样的二进制流。SOME/IP可以承接应用层的一些数据,进行打包放到传输层。

usstmiracle的博客 618

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

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

海盗Sharp的博客 307

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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

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

海盗Sharp的博客 1384

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

设置ODBC的自定义类CSetODBC

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

闻缺陷则喜何志丹 3116

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

微软技术周报 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的博客 426

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

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

kk_net8899的博客 169

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

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

海盗Sharp的博客 367

【测评】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 390

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的博客 209

微软 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的博客 450
上一篇: 混合编程关键词
下一篇: 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、付费专栏及课程。

余额充值