Assigning border to every Grid row
Solution 1
You could pull that border out into a reusable resource, but I suspect what you're really trying to do is create a GridView.
Solution 2
Or you could use this grid I just made. It will automatically add a border to every cell in the grid. This is the result:
C#:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace GridWithBorder
{
public class BorderGrid : Grid
{
protected override void OnRender(DrawingContext dc)
{
double leftOffset = 0;
double topOffset = 0;
Pen pen = new Pen(Brushes.Black, 3);
pen.Freeze();
foreach (RowDefinition row in this.RowDefinitions)
{
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
topOffset += row.ActualHeight;
}
// draw last line at the bottom
dc.DrawLine(pen, new Point(0, topOffset), new Point(this.ActualWidth, topOffset));
//foreach (ColumnDefinition column in this.ColumnDefinitions)
//{
// dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, this.ActualHeight));
// leftOffset += column.ActualWidth;
//}
// draw last line on the right
//dc.DrawLine(pen, new Point(leftOffset, 0), new Point(leftOffset, this.ActualHeight));
base.OnRender(dc);
}
}
}
XAML:
<Window x:Class="GridWithBorder.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GridWithBorder"
Title="MainWindow" Height="350" Width="525">
<local:BorderGrid>
<local:BorderGrid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</local:BorderGrid.RowDefinitions>
<local:BorderGrid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</local:BorderGrid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Fill="Red" Margin="5" />
<Rectangle Grid.Row="0" Grid.Column="1" Fill="Blue" Margin="5" />
<Rectangle Grid.Row="0" Grid.Column="2" Fill="Orange" Margin="5" />
<Rectangle Grid.Row="0" Grid.Column="3" Fill="Red" Margin="5" />
<Rectangle Grid.Row="1" Grid.Column="0" Fill="Yellow" Margin="5" />
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Green" Margin="5" />
<Rectangle Grid.Row="1" Grid.Column="2" Fill="Purple" Margin="5" />
<Rectangle Grid.Row="1" Grid.Column="3" Fill="Green" Margin="5" />
<Rectangle Grid.Row="2" Grid.Column="0" Fill="Orange" Margin="5" />
<Rectangle Grid.Row="2" Grid.Column="1" Fill="Red" Margin="5" />
<Rectangle Grid.Row="2" Grid.Column="2" Fill="Blue" Margin="5" />
<Rectangle Grid.Row="2" Grid.Column="3" Fill="Red" Margin="5" />
</local:BorderGrid>
</Window>
Solution 3
You can just set the Background
property on your Grid
. If there is commonality between the border which you are applying to the different rows, you can create a default style (and if desired, limit the scope of this style to the Grid
itself):
XAML
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Border}">
<!-- All rows -->
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="CornerRadius" Value="5" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Grid.Row="0">
<TextBlock Text="This row has a black border (default)." />
</Border>
<Border BorderBrush="Red" Grid.Row="1">
<TextBlock Text="This row has a red border." />
</Border>
<Border BorderBrush="Green" BorderThickness="4" Grid.Row="2">
<TextBlock Text="This has a thick green border." />
</Border>
</Grid>
With a default Style
, no additional property needs to be set on your row's Border
to achieve a default look (row one above). If a certain row needs to tweak the look and feel, then just provide additional properties on the Border
to override the ones set in the default Style
(rows two and three above). If this technique is something you are applying across multiple views in your application, then you can extract this style into a separate ResourceDictionary
and simply merge it where appropriate.
Hope this helps!
dotancohen
I currently develop and support the backends of a few LAMP-stack based web applications for BSS (Business Support Services) that my company specializes in. I have experience in software project management, business process development, and I ran a software development business for a short time (actually twice). I have been using PHP since 1998 or '99, and I'm reasonably competent in the associated client-side technologies. I find myself using Python often, mostly for my own personal projects, I'm quite poetic in VIM, and of course Git is a cornerstone of my development. Lately I have been experimenting with machine learning, mostly with scikit-learn.
Updated on August 26, 2020Comments
-
dotancohen almost 4 years
Currently I am setting the background on each Grid row individually:
<Grid> <Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions> <Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /><ColumnDefinition /><ColumnDefinition /><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions> <Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="6" Height="24" BorderBrush="#FF252A30" CornerRadius="10" BorderThickness="1"> <Border.Background> <LinearGradientBrush EndPoint="1.036,0.367" StartPoint="-0.194,0.362"> <GradientStop Color="#AAE098" Offset="0.1"/> <GradientStop Color="#D5E9D4" Offset="0.9"/> </LinearGradientBrush> </Border.Background> </Border> <Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="6" Height="24" BorderBrush="#FF252A30" CornerRadius="10" BorderThickness="1"> <Border.Background> <LinearGradientBrush EndPoint="1.036,0.367" StartPoint="-0.194,0.362"> <GradientStop Color="#AAE098" Offset="0.1"/> <GradientStop Color="#D5E9D4" Offset="0.9"/> </LinearGradientBrush> </Border.Background> </Border> </Grid>
Surely there must be some way to set this Border once for all rows. How is that done?
Thanks!
-
dotancohen over 12 yearsHello F Ruffell! The background is not solid across the entire Grid, rather, each row has it's own rounded corners at the beginning of the first cell and at the end of the last cell. Also, the example that you mention still requires the dev to update the Border element for each row individually if the requirement for the BorderThickness changes.
-
FunnyItWorkedLastTime over 12 yearsBy moving the commonly set properties into a default style that is scoped to the Grid, then the Border element does not properties to be set (other than color for example), and this approach does not repeat itself (e.g. BorderThickness is specified once only and hence needs to be updated only once). See edited response above :)
-
dotancohen over 12 yearsThanks, this is clever. I am having a hard time modifying it to put borders around each row, not each cell. Nice idea, though, until this point I was trying to do it only in XAML.
-
Carlo over 12 years@dotancohen ah ok, then just comment the part I just commented in the C# code, you'll get this result screencast.com/t/NwdxtGQNyq. Lmk if you need the first and last vertical lines (to have the border around the whole grid) I can do that too.
-
Carlo over 12 years@dotancohen example of border all around the grid and rows but not the columns here: screencast.com/t/d8GNqXRKGPf
-
dotancohen over 12 yearsThanks, Carlo, I am still playing with it. I need to figure out what properties are valid in the foreach, and I've gone through all the Intellisense suggestions but I cannot seem to find a read Background property. The issue is not only borders, it is also rounded corners and a solid background. Pen can't do that! This is how the code in the original post displays, I need to learn to create all those effects. Note that the rows are bound to an ObservableCollection so they will be updated on the fly.
-
Carlo over 12 yearsAh ok, that can be done but it could get a little more complex (and fun!), I'll certainly look into it as soon as I get some time.
-
dotancohen over 12 yearsI think that you are definitely right. What is the 'reusable resource' that into which I can put the border?
-
dotancohen over 12 yearsActually, I do agree that XAML is fun! I wouldn't say the same for some technologies but the whole non-C-based .NET stack (XAML and Linq for instance) really are entertaining to use and learn. Thank you for the help, it certainly helps to get me on the track of what to Google for.
-
dotancohen over 12 years@F Ruffell: Thank you, but the styles still affect only individual cells, not entire rows. To demonstrate, if you add Grid.Column attributes to the Border elements, then it can be seen that each cell has rounded edges, not each row. My goal is to have each row a solid colour, but with rounded edges at the corners of the row. The code in the OP does this, but it needs to be defined (and updated) for each row individually. I would like to abstract that into a style that is reused for each row.