Wpf之HandyControls与MaterialDesign混用之DataGrid

首先在App.Xaml引入相关资源
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--Handy Control-->
            <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/>
            <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml"/>

            <!--Material Design-->
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/materialdesigncolor.blue.xaml" />
            <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />

            <!--Geometry-->
            <ResourceDictionary Source="pack://application:,,,/Resources/Icons/Icons.xaml"/>
            <!--Custom Styles-->
            <ResourceDictionary Source="pack://application:,,,/Resources/Theme/AppBaseStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <local:AppLocator  x:Key="Locator"/>
    </ResourceDictionary>
</Application.Resources>
定义好DataGrid Style在引入到AppBaseStyle中, 下面是DataGrid.xaml的定义
<ResourceDictionary xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="//schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:md="//materialdesigninxaml.net/winfx/xaml/themes"
                    xmlns:hc="//handyorg.github.io/handycontrol">
    <!--<Style x:Key="LSTextBlockComboBoxStyle" TargetType="ComboBox">
        <Setter Property="Focusable" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ComboBox">
                    <TextBlock IsHitTestVisible="False" Text="{TemplateBinding Text}" TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>-->
    <Style x:Key="LSTextBlockComboBoxStyle"
           TargetType="{x:Type ComboBox}"
           BasedOn="{StaticResource MaterialDesignDataGridComboBox}">
        <Setter Property="IsHitTestVisible" Value="False" />
        <Setter Property="Focusable" Value="False" />
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>
    <Style x:Key="LSTextBlockComboBoxEditingStyle"
           TargetType="{x:Type ComboBox}"
           BasedOn="{StaticResource MaterialDesignDataGridComboBox}">
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>
    <Style x:Key="LSDataGridTextColumnStyle" TargetType="TextBlock">
        <Setter Property="TextTrimming" Value="CharacterEllipsis"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>
    <Style TargetType="DataGrid">
        <Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"/>
        <Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}"/>
        <Setter Property="BorderBrush" Value="{DynamicResource MaterialDesignTextBoxBorder}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="EnableRowVirtualization" Value="True"/>

        <Setter Property="CanUserAddRows" Value="False"/>
        <Setter Property="CanUserDeleteRows" Value="False"/>
        <Setter Property="CanUserReorderColumns" Value="False"/>
        <Setter Property="CanUserResizeRows" Value="False"/>

        <Setter Property="FontSize" Value="13"/>
        <Setter Property="GridLinesVisibility" Value="Horizontal" />
        <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
        <Setter Property="HeadersVisibility" Value="Column" />
        <Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource MaterialDesignSelection}" />

        <!--
        <Setter Property="ColumnHeaderStyle" Value="{StaticResource MaterialDesignDataGridColumnHeader}"/>
        <Setter Property="RowHeaderStyle" Value="{StaticResource MaterialDesignDataGridRowHeader}"/>
        <Setter Property="RowStyle" Value="{StaticResource MaterialDesignDataGridRow}"/>
        <Setter Property="CellStyle" Value="{StaticResource MaterialDesignDataGridCell}"/>
        -->
        <Setter Property="ColumnHeaderStyle" Value="{StaticResource DataGridColumnHeaderStyle}"/>
        <Setter Property="RowHeaderStyle" Value="{StaticResource DataGridRowHeaderStyle}"/>
        <Setter Property="RowStyle" Value="{StaticResource MaterialDesignDataGridRow}"/>
        <Setter Property="CellStyle" Value="{StaticResource MaterialDesignDataGridCell}"/>

        <!--<Setter Property="md:DataGridAssist.AutoGeneratedCheckBoxStyle" Value="{StaticResource MaterialDesignDataGridCheckBoxColumnStyle}" />
        <Setter Property="md:DataGridAssist.AutoGeneratedEditingCheckBoxStyle" Value="{StaticResource MaterialDesignDataGridCheckBoxColumnEditingStyle}" />
        <Setter Property="md:DataGridAssist.AutoGeneratedEditingTextStyle" Value="{StaticResource MaterialDesignDataGridTextColumnEditingStyle}" />
        -->
        <Setter Property="md:DataGridAssist.EnableEditBoxAssist" Value="True" />

        <!--<Setter Property="hc:DataGridAttach.TextColumnStyle" Value="{StaticResource DataGridTextColumnStyle}"/>-->
        <Setter Property="hc:DataGridAttach.TextColumnStyle" Value="{StaticResource LSDataGridTextColumnStyle}"/>
        <Setter Property="hc:DataGridAttach.EditingTextColumnStyle" Value="{StaticResource TextBoxBaseStyle}"/>
        <Setter Property="hc:DataGridAttach.ComboBoxColumnStyle" Value="{StaticResource LSTextBlockComboBoxStyle}"/>
        <Setter Property="hc:DataGridAttach.EditingComboBoxColumnStyle" Value="{StaticResource LSTextBlockComboBoxEditingStyle}"/>
        <Setter Property="hc:DataGridAttach.CheckBoxColumnStyle" Value="{StaticResource CheckBoxBaseStyle}"/>
        <Setter Property="hc:DataGridAttach.EditingCheckBoxColumnStyle" Value="{StaticResource CheckBoxBaseStyle}"/>
        <Setter Property="hc:DataGridAttach.ApplyDefaultStyle" Value="True"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGrid}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
                            <ScrollViewer.Template>
                                <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition Height="*"/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <Button Command="{x:Static DataGrid.SelectAllCommand}" Focusable="false" Style="{DynamicResource {ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}}" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.All}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Width="{Binding CellsPanelHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                        <Border BorderThickness="0 0 0 1" BorderBrush="{DynamicResource MaterialDesignDivider}"
                                                Grid.Row="0" Grid.Column="1" Visibility="{Binding HeadersVisibility, ConverterParameter={x:Static DataGridHeadersVisibility.Column}, Converter={x:Static DataGrid.HeadersVisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}">
                                            <DataGridColumnHeadersPresenter x:Name="PART_ColumnHeadersPresenter" />
                                        </Border>
                                        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" Grid.ColumnSpan="2"
                                                                Grid.Column="0" Grid.Row="1"/>
                                        <ScrollBar x:Name="PART_VerticalScrollBar" Grid.Column="2" Maximum="{TemplateBinding ScrollableHeight}" Orientation="Vertical" Grid.Row="1" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
                                        <Grid Grid.Column="1" Grid.Row="2">
                                            <Grid.ColumnDefinitions>
                                                <ColumnDefinition Width="{Binding NonFrozenColumnsViewportHorizontalOffset, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                                <ColumnDefinition Width="*"/>
                                            </Grid.ColumnDefinitions>
                                            <ScrollBar x:Name="PART_HorizontalScrollBar" Grid.Column="1" Maximum="{TemplateBinding ScrollableWidth}" Orientation="Horizontal" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
                                        </Grid>
                                    </Grid>
                                </ControlTemplate>
                            </ScrollViewer.Template>
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsGrouping" Value="true"/>
                    <Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
            </MultiTrigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>
效果如下

其它
  1. 在datagrid中使用ComboboxColumn时会遇到一些绑定与显示的问题, 解决方案是分别定义ComboboxColumnSytle和ComboboxColumnEditingStyle, 此方法需要麻烦但是可以解决Combobox在DataGrid中的问题
<DataGridComboBoxColumn Header="节目类型">
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                AncestorType=DataGrid}, Path=DataContext.Categories.Result}"/>
            <Setter Property="DisplayMemberPath" Value="Title"/>
            <Setter Property="SelectedValuePath" Value="Id"/>
            <Setter Property="SelectedValue" Value="{Binding CategoryId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
            <Setter Property="SelectedItem" Value="{Binding CategoryModel, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                AncestorType=DataGrid}, Path=DataContext.Categories.Result}"/>
            <Setter Property="DisplayMemberPath" Value="Title"/>
            <Setter Property="SelectedValuePath" Value="Id"/>
            <Setter Property="SelectedValue" Value="{Binding CategoryId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
            <Setter Property="SelectedItem" Value="{Binding CategoryModel, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>
  1. 使用MaterialDesign的DataGridComboboxColumn
<md:DataGridComboBoxColumn Header="节目类型"
    ItemsSourceBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=DataContext.Categories.Result}"
    DisplayMemberPath="Title" SelectedValuePath="Id"
    SelectedValueBinding="{Binding CategoryId, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
    SelectedItemBinding="{Binding CategoryModel, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
Tags: