I'm building a grid in Xamarin.Forms.
And I'd like to add borders like tables.
I thought that I could add the border when defining rows and columns, but failed.
Can anyone help me?
This is my current code.
Grid grid = new Grid {
VerticalOptions = LayoutOptions.FillAndExpand,
RowDefinitions = {
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto },
},
ColumnDefinitions = {
new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) },
new ColumnDefinition { Width = new GridLength (5, GridUnitType.Star) },
new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) },
}
};
There's no Border property for GridView, but:
Just set grid.BackgroundColor to your desired border color value, then set grid.ColumnSpacing and grid.RowSpacing to some value and make sure all controls you add to the grid have own BackgroundColor set correctly.
Here is the full answer (in XAML) without needing to write a custom renderer or Effect.
The code is little verbose but easy to understand and the result is like on the image
Here is the code to put the borders on your grid (and whats more you´ll have total control over them like you notice there is no blue line on the far left)
<Grid BackgroundColor="White">
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition Height="15"/>
<RowDefinition Height="1"/>
<RowDefinition Height="15"/>
<RowDefinition Height="1"/>
<RowDefinition Height="15"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="1" />
</Grid.ColumnDefinitions>
<BoxView Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="8" BackgroundColor="Red" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
<!--Your stuff here!-->
<BoxView Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="8" BackgroundColor="Red" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
<!--Your stuff here!-->
<BoxView Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="8" BackgroundColor="Red" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
<!--Your stuff here!-->
<BoxView Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="8" BackgroundColor="Red" HeightRequest="1" VerticalOptions="End" HorizontalOptions="FillAndExpand"/>
<!--Vertical lines and no "stuff"-->
<BoxView Grid.Column="1" Grid.Row="0" Grid.RowSpan="7" BackgroundColor="Blue" WidthRequest="1" VerticalOptions="FillAndExpand" HorizontalOptions="End"/>
<BoxView Grid.Column="3" Grid.Row="0" Grid.RowSpan="7" BackgroundColor="Blue" WidthRequest="1" VerticalOptions="FillAndExpand" HorizontalOptions="End"/>
<BoxView Grid.Column="5" Grid.Row="0" Grid.RowSpan="7" BackgroundColor="Blue" WidthRequest="1" VerticalOptions="FillAndExpand" HorizontalOptions="End"/>
<BoxView Grid.Column="7" Grid.Row="0" Grid.RowSpan="7" BackgroundColor="Blue" WidthRequest="1" VerticalOptions="FillAndExpand" HorizontalOptions="End"/>
</Grid>
<Grid BackgroundColor="White" >
<BoxView BackgroundColor="Pink" />
<Grid BackgroundColor="White" Margin="5">
</Grid>
</Grid>
Just noticed my example is similar to Sturla's but a little different so I will leave it up.
The code is not super pretty but I did something similar by adding a 1px BoxView between each column and then 1 on top of your Grid and one on the bottom of your Grid, like so:
<Grid VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
RowSpacing="0"
ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1"/>
</Grid.RowDefinitions>
<BoxView BackgroundColor="Black"
HeightRequest="1"
HorizontalOptions="FillAndExpand"
Grid.Row="0"/>
<Grid VerticalOptions="Start"
ColumnSpacing="0"
Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Text="Button 1"/>
<BoxView BackgroundColor="Black"
WidthRequest="1"
VerticalOptions="FillAndExpand"
Grid.Column="1"/>
<Button Text="Button 1"
Grid.Column="2"/>
</Grid>
<BoxView BackgroundColor="Black"
HeightRequest="1"
HorizontalOptions="FillAndExpand"
Grid.Row="2"/>
</Grid>
*Edit: Since writing this, I have changed the way I do it a bit. Now, like Daniel Luberda's answer, I simply set the Grid.BackgroundColor to Color.Black and then I can remove all of the BoxViews and I am done. I do this because I assume it is much better to have few views on the screen, especially if you are putting something like the above in a ListView.
Also, since a lot of my pages will animate the Buttons when the page load (using ScaleTo()) I initially set the Grid.BackgroundColor to Color.Transparent or Color.White and then once the animation is done, I change it to Color.Black. Has worked pretty well so far.
If you would like a solution with more equal borders than Daniel Luberda'S anwser, here's what i used :
Make a Grid in which you want element to have borders. Put the spacing between colomns and rows to 0. For each element of the Grid make another Grid with a Boxview in it, and your view on top of that Boxview. Then,put each BoxView to fill and expand. Then adjust the padding of these "under"-Grids as you'd like. Each element of your grid will be separated equaly.
This is pretty heavy though.
Related
I am creating a history screen and need to make a dashed vertical line and a left arrow.
I created a list of items that are populating the data but couldn't continue. I will leave below an image of the expected result and the way it is currently.
Can anyone help me, please?
Thanks!
Code
<ListView x:Name="timelineListView"
ItemTapped="timelineListView_ItemTapped"
CachingStrategy="RecycleElement"
HasUnevenRows="True"
SeparatorVisibility="None"
Margin="0, 15, 0, 0">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Margin="0, 0, 0, 20"
Padding="20, 0, 0, 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.15*" />
<ColumnDefinition Width="0.85*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Tipo Histórico-->
<BoxView Color="{StaticResource CorBranco}"
Grid.Row="0"
Grid.Column="0"
WidthRequest="40"
CornerRadius="200"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand" />
<Image Aspect="AspectFit"
Grid.Row="0"
Grid.Column="0"
Margin="-10, 0, 0, 0"
HorizontalOptions="Center"
VerticalOptions="Center"
Source="{Binding ImagemTipoHistorico}" />
<Frame Margin="0, 0, 35, 0"
Padding="20, 10, 10, 10"
Grid.Row="0"
Grid.Column="1"
CornerRadius="10"
HasShadow="True"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
BackgroundColor="{StaticResource CorBranco}">
<Frame.Effects>
<effects:ShadowEffect Color="{StaticResource CorCinzaBordaFrame}"
Radius="0.1"
DistanceX="0"
DistanceY="4" />
</Frame.Effects>
<Grid Style="{StaticResource EstiloGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.8*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Descrição Tipo Histórico -->
<Label VerticalOptions="FillAndExpand"
HorizontalOptions="StartAndExpand"
LineBreakMode="TailTruncation"
Grid.Row="0"
Grid.Column="0"
FontSize="18"
Text="{Binding DescricaoTipoHistorico}"
FontFamily="{StaticResource FonteFilsonSoftBlack}"
TextColor="{StaticResource CorPreto}" />
<!-- Horas -->
<Label VerticalOptions="CenterAndExpand"
HorizontalOptions="End"
Grid.Row="0"
Grid.Column="1"
FontSize="10"
Text="{Binding HoraDataRealizado}"
FontFamily="{StaticResource FonteFilsonSoftBlack}"
TextColor="{StaticResource CorCinzaClaro4}" />
<!-- Nome PDV -->
<Label VerticalOptions="FillAndExpand"
HorizontalOptions="StartAndExpand"
LineBreakMode="TailTruncation"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0, 5, 0, 0"
FontSize="16"
Text="{Binding NomePdv}"
FontFamily="{StaticResource FonteFilsonSoftBlack}"
TextColor="{StaticResource CorCinzaPadrao}" />
</Grid>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Expected:
Currently:
You can use skia sharp to achieve both of your requirements. But Jason's comment is more easier for the arrow.
Dashed lines MS Docs
DashedLine.Xaml
<ContentView.Content>
<skia:SKCanvasView
PaintSurface="OnCanvasViewPaintSurface"/>
</ContentView.Content>
DashedLine.Xaml.cs
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Gray,
StrokeWidth = 3,
PathEffect = SKPathEffect.CreateDash(new float[] { 10, 10 }, 20)
};
SKPath path = new SKPath();
path.MoveTo(info.Width / 2, 0);
path.LineTo(info.Width / 2, info.Height);
canvas.DrawPath(path, paint);
}
ArrowView.Xaml:
<ContentView.Content>
<skia:SKCanvasView
x:Name="arrowView"
PaintSurface="OnCanvasViewPaintSurface">
</skia:SKCanvasView>
</ContentView.Content>
ArrowView.Xaml.cs
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.White,
StrokeWidth = 1,
};
SKPath path = new SKPath();
path.MoveTo(0, info.Height / 2);
path.LineTo(info.Width, info.Height * 3 / 4);
path.LineTo(info.Width, info.Height / 4);
path.Close();
canvas.DrawPath(path, paint);
}
}
Use the DashedLine and ArrowView in your case:
1.Add the DashedLine view to the same grid space as the BoxView
<local:DashedLines/>
<!-- Tipo Histórico-->
<BoxView Color="White"
Grid.Row="0"
Grid.Column="0"
WidthRequest="40"
CornerRadius="200"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand" />
2.Add the ArrowView by creating a column to the left of your Frame view.
<local:DashedLines/>
<!-- Tipo Histórico-->
<BoxView Color="White"
Grid.Row="0"
Grid.Column="0"
WidthRequest="40"
CornerRadius="200"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand" />
<Grid
Grid.Row="0"
ColumnSpacing="0"
Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<local:ArraowView/>
<Frame
Padding="0, 10, 10, 10"
Grid.Row="0"
Grid.Column="1"
CornerRadius="10"
HasShadow="True"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand">
UI result: (Requires changes in Padding and margin)
Hope this could help you! Regarding the in first and last items, the dashes needs to be only half way. For this you could use some DataTemplateSelector
I have the following Xaml code:
<StackLayout>
<Button Text="Take a picture" Clicked="Button_Clicked_1" />
<Grid x:Name="MainPageBluePrintGrid" BackgroundColor="BlueViolet" HeightRequest="100">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Text="A" Grid.Row="0" Grid.Column="0"/>
<Label Text="B" Grid.Row="0" Grid.Column="1"/>
<Label Text="C" Grid.Row="0" Grid.Column="2"/>
<Image x:Name="image1" Grid.Row="1" Grid.Column="0"/>
<Image x:Name="image2" Grid.Row="1" Grid.Column="1"/>
<Image x:Name="image3" Grid.Row="1" Grid.Column="2"/>
</Grid>
<StackLayout BackgroundColor="BurlyWood">
<Image x:Name="CapturedImage"/>
</StackLayout>
</StackLayout>
The second row is images, which are picked by the user. Is it possible to take a screenshot only of the second row of GridView, and display it in the <Image x:Name="CapturedImage"/>. I have search how to do it, but I only came across full screen capture, which is not ideal in my case.
Sounds like you want to create a snapshot of a specific Xamarin.Forms.View. You should wrap the 2nd Grid.Row by a single top level View that will contain the images as children. After that you could use platform specific capabilities to create a snapshot.
Android
public void MakeViewShot(Xamarin.Forms.View view)
{
var nativeView = view.GetRenderer().View;
var wasDrawingCacheEnabled = nativeView.DrawingCacheEnabled;
nativeView.DrawingCacheEnabled = true;
nativeView.BuildDrawingCache(false);
var bitmap = nativeView.GetDrawingCache(false);
// TODO: Save bitmap and return filepath
nativeView.DrawingCacheEnabled = wasDrawingCacheEnabled;
}
iOS
public void MakeViewShot(Xamarin.Forms.View view)
{
var nativeView = Xamarin.Forms.Platform.iOS.Platform.GetRenderer(view).NativeView;
UIGraphics.BeginImageContextWithOptions(nativeView.Bounds.Size, opaque: true, scale: 0);
nativeView.DrawViewHierarchy(nativeView.Bounds, afterScreenUpdates: true);
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
// TODO: Save bitmap and return filepath
}
Usage example:
<StackLayout
x:Name="secondRow"
Grid.Row="1">
<Image x:Name="image1" />
<Image x:Name="image2" />
<Image x:Name="image3" />
</StackLayout>
MakeViewShot(secondRow);
First of all im just starting with xamarin forms, and c# i have managed to use listviews, however im a lil bit confused when it comes to grids, basically what i need is to bind an object to a serie of grids that behave like this:
2 columns per row, i have managed to do it with this code:
<Grid HorizontalOptions="Fill" VerticalOptions="Fill" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!--fila 1-->
<StackLayout Grid.Column="0" Grid.Row="0" BackgroundColor="Blue" HorizontalOptions="Fill"></StackLayout>
<StackLayout Grid.Column="1" Grid.Row="0" BackgroundColor="Red" HorizontalOptions="Fill"></StackLayout>
<!--fila 2-->
<StackLayout Grid.Column="0" Grid.Row="1" BackgroundColor="Red" HorizontalOptions="Fill"></StackLayout>
<StackLayout Grid.Column="1" Grid.Row="1" BackgroundColor="Blue" HorizontalOptions="Fill"></StackLayout>
<!--fila 3-->
<StackLayout Grid.Column="0" Grid.Row="2" BackgroundColor="Blue" HorizontalOptions="Fill"></StackLayout>
<StackLayout Grid.Column="1" Grid.Row="2" BackgroundColor="Red"
HorizontalOptions="Fill"></StackLayout>
</Grid>
However, i dont know how to fill the grids with information dynamically. with the listview is quite simple since its only with the bind command, here i dont have idea, can someone please point me into the right direction?
thanks.
int row = 0;
int col = 0;
// data is a List<string>
foreach (var text in data) {
var label = new Label() { Text = text };
grid.Children.Add(box, col, row);
col++;
if (col > 1) {
col = 0;
row++;
}
}
I have following WPF XAML file,
<Window x:Class="Program"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Program"
mc:Ignorable="d"
Title="Print Preview" Height="40820.962" Width="2135.146">
<Grid Margin="10,10,2,-21" Height="40801" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="131*"/>
<RowDefinition Height="40670*"/>
</Grid.RowDefinitions>
<Grid HorizontalAlignment="Left" Height="3438" Margin="20,126,0,0" VerticalAlignment="Top" Width="2095" Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500*"/>
<ColumnDefinition Width="1072*"/>
<ColumnDefinition Width="523*"/>
</Grid.ColumnDefinitions>
<Label x:Name="label5" Content="Here" Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="-7.455,-0.374" Height="58" Width="171" FontSize="16"/>
</Grid>
<Grid HorizontalAlignment="Right" Height="432" Margin="0,3453,1605,0" Grid.Row="1" VerticalAlignment="Top" Width="490" RenderTransformOrigin="0.62,1.205">
<Grid.RowDefinitions>
<RowDefinition Height="143*"/>
<RowDefinition Height="136*"/>
<RowDefinition Height="153*"/>
</Grid.RowDefinitions>
</Grid>
<Grid HorizontalAlignment="Right" Height="452" Margin="0,3433,1605,0" Grid.Row="1" VerticalAlignment="Top" Width="490" RenderTransformOrigin="0.62,1.205">
<Grid.RowDefinitions>
<RowDefinition Height="143*"/>
<RowDefinition Height="136*"/>
<RowDefinition Height="153*"/>
</Grid.RowDefinitions>
</Grid>
<Grid HorizontalAlignment="Left" Height="447" Margin="1594,3438,0,0" Grid.Row="1" VerticalAlignment="Top" Width="511">
<Grid.RowDefinitions>
<RowDefinition Height="142*"/>
<RowDefinition Height="156*"/>
<RowDefinition Height="149*"/>
</Grid.RowDefinitions>
</Grid>
<Grid HorizontalAlignment="Left" Height="452" Margin="510,3433,0,0" Grid.Row="1" VerticalAlignment="Top" Width="1084">
<Grid.RowDefinitions>
<RowDefinition Height="44*"/>
<RowDefinition Height="45*"/>
</Grid.RowDefinitions>
</Grid>
<Grid HorizontalAlignment="Left" Height="23141" Margin="20,3895,0,0" Grid.Row="1" VerticalAlignment="Top" Width="1574"/>
<Grid HorizontalAlignment="Left" Height="23540" Margin="1599,3496,0,0" Grid.Row="1" VerticalAlignment="Top" Width="506">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14.143"/>
<ColumnDefinition Width="146.857"/>
<ColumnDefinition Width="42.714"/>
<ColumnDefinition Width="119*"/>
<ColumnDefinition Width="98*"/>
<ColumnDefinition Width="85*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="87*"/>
<RowDefinition Height="23516*"/>
</Grid.RowDefinitions>
<Label x:Name="label" Content="Hespanic" HorizontalAlignment="Left" Margin="-1,-61,0,0" VerticalAlignment="Top" Height="55" Width="506" FontSize="22" Grid.ColumnSpan="6"/>
</Grid>
<Label x:Name="label1" Content="Sample" HorizontalAlignment="Left" Margin="8,97,0,0" VerticalAlignment="Top" RenderTransformOrigin="-8.5,0.654" Width="215"/>
<Label x:Name="label2" Content="Layer" HorizontalAlignment="Left" Height="33" Margin="922,10,0,0" VerticalAlignment="Top" Width="232" FontSize="18"/>
<Label x:Name="label3" Content="Index" HorizontalAlignment="Left" Margin="1969,10,0,0" VerticalAlignment="Top" Width="105"/>
<Label x:Name="label4" Content="People" HorizontalAlignment="Left" Margin="1477,84,0,0" VerticalAlignment="Top" Width="161"/>
</Grid>
</Window>
So I'm trying to add thickness = 1, outline for grid borders, rows and columns
So I tried following thread
How do i put a border on my grid in WPF?
So to add a border I added following thing, and its working fine
<Border BorderBrush="Black" BorderThickness="2">
<Grid>
<!-- Grid contents here -->
</Grid>
</Border>
But since I have need to add thickness = 1, outline for all above multiple columns and rows also, I tried something like this
</Grid.ColumnDefinitions>
<Border Grid.Row="0" Grid.Column="0" BorderThickness="1" BorderBrush="Black"/>
<Border Grid.Row="0" Grid.Column="1" BorderThickness="1" BorderBrush="Black"/>
which is identifying each column and row and add thickness to them, but this seems quite time consuming and confusing work.
Is there any other proper and quick way to add BorderThickness="1" BorderBrush="Black" to all above Columns and Rows in the grids ?
In the default WPF Grid, you can set ShowGridLines="True". However these lines are meant to be designer lines, and not meant for end use.
The common solution I use is a custom GridControl which adds DependencyProperties for GridLines settings, and overrides OnRender to draw them.
public class GridControl : Grid
{
#region Properties
public bool ShowCustomGridLines
{
get { return (bool)GetValue(ShowCustomGridLinesProperty); }
set { SetValue(ShowCustomGridLinesProperty, value); }
}
public static readonly DependencyProperty ShowCustomGridLinesProperty =
DependencyProperty.Register("ShowCustomGridLines", typeof(bool), typeof(GridControl), new UIPropertyMetadata(false));
public Brush GridLineBrush
{
get { return (Brush)GetValue(GridLineBrushProperty); }
set { SetValue(GridLineBrushProperty, value); }
}
public static readonly DependencyProperty GridLineBrushProperty =
DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridControl), new UIPropertyMetadata(Brushes.Black));
public double GridLineThickness
{
get { return (double)GetValue(GridLineThicknessProperty); }
set { SetValue(GridLineThicknessProperty, value); }
}
public static readonly DependencyProperty GridLineThicknessProperty =
DependencyProperty.Register("GridLineThickness", typeof(double), typeof(GridControl), new UIPropertyMetadata(1.0));
#endregion
protected override void OnRender(DrawingContext dc)
{
if (ShowCustomGridLines)
{
foreach (var rowDefinition in RowDefinitions)
{
dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(0, rowDefinition.Offset), new Point(ActualWidth, rowDefinition.Offset));
}
foreach (var columnDefinition in ColumnDefinitions)
{
dc.DrawLine(new Pen(GridLineBrush, GridLineThickness), new Point(columnDefinition.Offset, 0), new Point(columnDefinition.Offset, ActualHeight));
}
dc.DrawRectangle(Brushes.Transparent, new Pen(GridLineBrush, GridLineThickness), new Rect(0, 0, ActualWidth, ActualHeight));
}
base.OnRender(dc);
}
static GridControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridControl), new FrameworkPropertyMetadata(typeof(GridControl)));
}
}
It can be used like this :
<local:GridEx ShowCustomGridLines="True"
GridLineBrush="#FF38B800"
GridLineThickness="2">
...
</local:GridEx>
I have the following layou:
<s:SurfaceWindow x:Class="Prototype_Concept_2.SurfaceWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
Title="Prototype_Concept_2"
>
<s:SurfaceWindow.Resources>
<ImageBrush x:Key="WindowBackground" Stretch="None" Opacity="0.6" ImageSource="pack://application:,,,/Resources/WindowBackground.jpg"/>
</s:SurfaceWindow.Resources>
<Grid Background="{StaticResource WindowBackground}" >
<Grid Name="ProjectsGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Name="ProjectsHeader" Grid.ColumnSpan="2" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="25" Text="Please choose one of the following projects" Grid.Row="0"></TextBox>
<s:SurfaceButton Name="BottomButton" HorizontalAlignment="Right" FontSize="20" Width="100" Grid.Column="1" Grid.Row="2" Foreground="White" Content="Refresh"></s:SurfaceButton>
<s:SurfaceListBox Background="Black" Grid.ColumnSpan="2" Name="ProjectsList" Grid.Row="1" ItemsSource="{Binding Projects}"></s:SurfaceListBox>
<Label Name="ProjectsFooter" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" FontSize="15" Content="Fetching projects data ..."></Label>
</Grid>
<Grid ShowGridLines="True" Name="SmellHeader" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
<ColumnDefinition Width="256"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="38"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="0" Grid.Row="0" s:Contacts.PreviewContactDown="BrainClass_PreviewContactDown">
<Label Background="Black" Foreground="White" Content="BrainClass" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="1" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="1" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="God Class" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="2" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="2" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="Tradition Breaker" HorizontalContentAlignment="Center"></Label>
</Viewbox>
<Rectangle Grid.Column="3" Grid.Row="0" Fill="Black"></Rectangle>
<Viewbox Grid.Column="3" Grid.Row="0">
<Label Background="Black" Foreground="White" Content="RefusedParent Bequest" HorizontalContentAlignment="Center"></Label>
</Viewbox>
</Grid>
<Canvas Name="RootLayer" Grid.Row="1" Grid.ColumnSpan="4">
</Canvas>
</Grid>
</s:SurfaceWindow>
To the RootLayer I add some Ellipse. Later I want to reoder them:
internal void setFocus(SourceManager manager)
{
Console.WriteLine("Set focus to class " + getFullName());
foreach (SourceFile sf in manager.getBrainClasses())
{
sf.getVisualizer().Fill = Brushes.Red;
Canvas.SetZIndex(sf.getVisualizer(), 0);
}
this.getVisualizer().Fill = Brushes.Blue;
Canvas.SetZIndex(this.getVisualizer(), 1);
manager.window.RootLayer.InvalidateArrange();
manager.window.RootLayer.InvalidateVisual();
}
The Ellipse is referenced by this.getVisualizer();
However, nothing changes? How can I bring one Ellipse to the front?
It's not fully clear from your code post how the ellipses are added to the canvas but here is a small sample that does essentially what you want to do:
<Grid>
<Canvas x:Name="RootLayer" Width="500" Height="500" />
</Grid>
And in the constructor of the code behind, create some ellipses:
for (int i = 0; i < 10; i++)
{
Ellipse e = new Ellipse
{
Width = 100,
Height = 100,
Fill = new SolidColorBrush(
Color.FromArgb(0xDD,
(Byte) r.Next(255)
(Byte) r.Next(255)
(Byte) r.Next(255))),
Stroke = Brushes.Black,
StrokeThickness = 1,
};
e.MouseUp += new MouseButtonEventHandler(e_MouseUp);
Canvas.SetLeft(e, r.Next(400));
Canvas.SetTop(e, r.Next(400));
RootLayer.Children.Add(e);
}
Event handler to handle mouse click on the ellipses
void e_MouseUp(object sender, MouseButtonEventArgs e)
{
foreach (UIElement item in RootLayer.Children)
Panel.SetZIndex(item, 0);
Panel.SetZIndex((UIElement)sender, 1);
}
With the code above, whenever an ellipse is clicked (mouse up), it will raise above all the other ellipses in that canvas.