Reputation: 3460
I am trying to make a Sudoku game.
I have added the numbers to an GridView.
This is my Code in WPF.
<DataGrid x:Name="lst" ItemsSource="{Binding SudokoField, UpdateSourceTrigger=PropertyChanged}"</DataGrid>
I want to add borders to row 3-6-9 and columns 3-6-9.
How is this done?
// EDIT The red line in the colums are done, but I can't get them in the rows. This is the code now:
<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>
Upvotes: 0
Views: 2240
Reputation: 1052
You may override DataGrid.CellStyle and set cell border according to row index or column index, for example:
<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>
Also you must define 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; } }
}
Upvotes: 1
Reputation: 1524
I don't think there is an easy solution for what you asking for but this is an incomplete solution that could work for you, the code is not complete but it might give you an idea on how to proceed but i'm not sure if it this will even work.
For the Columns you will need to in addition to the text column two others templated columns: one with a left colored border and one with a right colored border for more info have a look at DataGridTemplateColumn Class for an example. You can then bind each column individually to SudokuRow.Colmn1, SudokuRow.Colmn2 and so on depending on how you designed your view model or how the columns are mapped.
For the rows:
Create a converter resource as such, this converter takes a row and returns its index in the data grid:
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();
}
}
To the change the rows border you can use DataTriggers which will be triggered based on the row index
<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>
Upvotes: 0