C#WPF,DataGrid将边框添加到特定字段

时间:2015-12-12 16:12:46

标签: c# wpf datagrid border

我正在尝试制作数独游戏 我已将数字添加到GridView中。

这是我在WPF中的代码。

<DataGrid x:Name="lst" ItemsSource="{Binding SudokoField, UpdateSourceTrigger=PropertyChanged}"</DataGrid>

我想在第3-6-9行和第3-6-9列添加边框。

current

desired

这是怎么做到的?

//编辑 列中的红线已完成,但我无法将它们放入行中。这是现在的代码:

 <DataGrid x:Name="lst" ItemsSource="{Binding SudokoField, UpdateSourceTrigger=PropertyChanged}"  GridLinesVisibility="None" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False" AutoGenerateColumns="True" CanUserAddRows="False" ColumnWidth="*" CanUserReorderColumns="False" HeadersVisibility="None" >
            <DataGrid.CellStyle>
                <Style TargetType="DataGridCell" >
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="DataGridCell">
                                <Border Name="cellBorder" BorderBrush="Black">
                                    <Border.Style>
                                        <Style TargetType="Border">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding RelativeSource=          {RelativeSource TemplatedParent}, Path=Column.DisplayIndex}" Value="2">
                                                    <Setter Property="BorderThickness">
                                                        <Setter.Value>
                                                            <Thickness Left="0" Right="1" Top="0" Bottom="0"/>
                                                        </Setter.Value>
                                                    </Setter>
                                                </DataTrigger>
                                                <DataTrigger Binding="{Binding RelativeSource=          {RelativeSource TemplatedParent}, Path=Column.DisplayIndex}" Value="5">
                                                    <Setter Property="BorderThickness">
                                                        <Setter.Value>
                                                            <Thickness Left="0" Right="1" Top="0" Bottom="0"/>
                                                        </Setter.Value>
                                                    </Setter>
                                                </DataTrigger>
         this part    --->>                        <DataTrigger Binding="{Binding RelativeSource=          {RelativeSource TemplatedParent}, Path=Row.DisplayIndex}" Value="2">
                                                    <Setter Property="BorderThickness">
                                                        <Setter.Value>
                                                            <Thickness Left="1" Right="1" Top="1" Bottom="1"/>
                                                        </Setter.Value>
                                                    </Setter>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </Border.Style>
                                    <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGrid.CellStyle>
        </DataGrid>

2 个答案:

答案 0 :(得分:1)

您可以根据行索引或列索引覆盖DataGrid.CellStyle并设置单元格边框,例如:

<DataGrid ItemsSource="{Binding}">
    <DataGrid.CellStyle>
        <Style TargetType="DataGridCell" >
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridCell">
                        <Border Name="rowBorder" BorderBrush="Red">
                            <Border Name="columnBorder" BorderBrush="Red">
                                <Border.Style>
                                    <Style TargetType="Border">
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Column.DisplayIndex}" Value="2">
                                                <Setter Property="BorderThickness">
                                                    <Setter.Value>
                                                        <Thickness Left="1" Right="0" Top="0" Bottom="0"/>
                                                    </Setter.Value>
                                                </Setter>
                                            </DataTrigger>
                                            <!--put column related triggers here-->
                                        </Style.Triggers>
                                    </Style>
                                </Border.Style>
                                <ContentPresenter Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content}" />
                            </Border>
                            <Border.Style>
                                <Style TargetType="Border">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}, Converter={x:Static local:RowToIndexConverter.Instance}}" Value="1">
                                            <Setter Property="BorderThickness">
                                                <Setter.Value>
                                                    <Thickness Left="0" Right="0" Top="1" Bottom="0"/>
                                                </Setter.Value>
                                            </Setter>
                                        </DataTrigger>
                                        <!--put row related triggers here-->
                                    </Style.Triggers>
                                </Style>
                            </Border.Style>                                    
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.CellStyle>
</DataGrid>

此外,您必须定义RowToIndexConverter:

public class RowToIndexConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (value as DataGridRow).GetIndex();
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }

    private static RowToIndexConverter _instance = new RowToIndexConverter(); 
    public static RowToIndexConverter Instance { get { return _instance; } }
}

答案 1 :(得分:0)

我不认为有一个简单的解决方案可以满足您的要求,但这是一个不完整的解决方案,可能对您有用,代码不完整,但它可能会让您知道如何继续但我和#39;我不确定这是否会起作用。

对于列,除了文本列之外,您还需要另外两个模板化列:一个带有左侧彩色边框,另一个带有右侧彩色边框以获取更多信息,请查看DataGridTemplateColumn Class示例。然后,您可以将每个列单独绑定到SudokuRow.Colmn1,SudokuRow.Colmn2等,具体取决于您设计视图模型的方式或列的映射方式。

对于行:

创建转换器资源,此转换器接受一行并在数据网格中返回其索引:

public class RowToIndexConverter : DependencyObject, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                             System.Globalization.CultureInfo culture)
    {
        return (value as DataGridRow).GetIndex();
    }

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

要更改行边框,您可以使用将根据行索引

触发的DataTriggers
<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="DataGridTemplateColumnWithLeftBorder" >
            <Border BorderBrush="RED" BorderThickness="0,1,0,0">
                <TextBlock Text={Binding }/>
            </Border>
        </DataTemplate>
        <DataTemplate x:Key="DataGridTemplateColumnWithRightBorder" >
            <Border BorderBrush="RED" BorderThickness="1,0,0,0">
                <TextBlock Text={Binding }/>
            </Border>
        </DataTemplate>
        //add RowToIndexConverter resource here so ... 
    </Grid.Resources>
    <DataGrid x:Name="lst" ItemsSource="{Binding SudokoField, UpdateSourceTrigger=PropertyChanged} >
        //columns with each mapped to a property
        <DataGrid.Columns>
            <DataGridTemplateColumn Binding={Column1} CellTemplate="{StaticResource DataGridTemplateColumnWithLeftBorder}" />
            <DataGridTextColumn Binding={Column2}>
            <DataGridTextColumn addbinding>
            <DataGridTemplateColumn addbinding CellTemplate="{StaticResource DataGridTemplateColumnWithLeftBorder}" />
            <DataGridTextColumn addbinding>
            <DataGridTextColumn addbinding/>
            <DataGridTemplateColumn addbinding CellTemplate="{StaticResource DataGridTemplateColumnWithLeftBorder}" />
            <DataGridTextColumn addbinding>
            <DataGridTemplateColumn addbinding CellTemplate="{StaticResource DataGridTemplateColumnWithRightBorder}" />
        </DataGrid.Columns>
        //Add RowStyle which defines DataTriggers that trigger depending on the row index: here row 0,3,6, and 8 will trigger. 
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RowToIndexConverter}" Value="0">
                       <Setter Property="BorderThickness" Value="0,1,0,0"/>
                       <Setter Property="BorderBrush" Value="Red"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding RowToIndexConverter}" Value="3">
                       <Setter Property="BorderThickness" Value="0,1,0,0"/>
                       <Setter Property="BorderBrush" Value="Red"/>                
                    </DataTrigger>
                    <DataTrigger Binding="{Binding RowToIndexConverter}" Value="6">
                       <Setter Property="BorderThickness" Value="0,1,0,0"/>
                       <Setter Property="BorderBrush" Value="Red"/>              
                    </DataTrigger>          
                    <DataTrigger Binding="{Binding RowToIndexConverter}" Value="8">
                       <Setter Property="BorderThickness" Value="1,0,0,0"/>
                       <Setter Property="BorderBrush" Value="Red"/>              
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>
</Grid>