WPF Grid white stripes - c#

I have a Grid with a lot of buttons inside. These buttons are supposed to be seamlessly connecting. In most of the cases, this is actually working, but sometimes there's a white stripe between the columns / rows of the grid:
I'm adding the buttons to the grid via the code behind like this (I'm sorry for non-minimal code, but I really don't know what might be relevant here):
public partial class MainWindow
{
private int _xCount;
private int _yCount;
public MainWindow ()
{
InitializeComponent ();
SetSize (40, 40);
}
public void SetSize (int x, int y)
{
_xCount = x;
_yCount = y;
Grid.ColumnDefinitions.Clear ();
Grid.RowDefinitions.Clear ();
for (var i = 0; i < x; i++)
Grid.ColumnDefinitions.Add (new ColumnDefinition {Width = new GridLength (100, GridUnitType.Star)});
for (var i = 0; i < y; i++)
Grid.RowDefinitions.Add (new RowDefinition {Height = new GridLength (100, GridUnitType.Star)});
for (var xI = 0; xI < x; xI++)
for (var yI = 0; yI < y; yI++)
{
var button = new Button
{
BorderThickness = new Thickness (1),
BorderBrush = Brushes.Gray,
Foreground = Brushes.DarkGray,
Content = "",
Background = Brushes.DarkGray
};
Grid.Children.Add (button);
Grid.SetColumn (button, xI);
Grid.SetRow (button, yI);
}
SetButtonSizes ();
}
private void SetButtonSizes ()
{
var gridWidth = Grid.Width;
var gridHeight = Grid.Height;
var buttonWidth = gridWidth / _xCount;
var buttonHeight = gridHeight / _yCount;
foreach (var button in Grid.Children)
{
((Button) button).Width = buttonWidth;
((Button) button).Height = buttonHeight;
}
}
protected override void OnRenderSizeChanged (SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged (sizeInfo);
SetButtonSizes ();
}
}
The WPF is pretty trivial and looks like that:
<Window x:Class="Minesweeper.MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow"
Height="1000"
Width="1000">
<Grid Name="Grid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Window>
I already tried Pixel Snapping, which didn't make any difference.

You should set UseLayoutRounding to true on the Grid and not programmatically resize the Buttons.
However, you could greatly simplify your code by using a UniformGrid
<Window ...>
<UniformGrid x:Name="grid"/>
</Window>
and add Buttons like this:
public MainWindow()
{
InitializeComponent();
SetSize(40, 40);
}
private void SetSize(int x, int y)
{
grid.Children.Clear();
grid.Columns = x;
for (int i = 0; i < x * y; i++)
{
grid.Children.Add(new Button
{
BorderThickness = new Thickness(1),
BorderBrush = Brushes.Gray,
Background = Brushes.DarkGray,
Foreground = Brushes.DarkGray,
Content = ""
});
}
}

Related

I need a responsive grid (cell can be clicked) on the form, what control should be used?

I need to show a grid on a Form, that displays as 32 by 32 cells, each cell can be clicked to do some operation(like the windows calendar app). I'v considered buttons and panels, but that'll be 1024 controls. any better way?
Here's a way to create a responsive grid with buttons in WPF:
The responsiveness is created with GridLength(1, GridUnitType.Star)
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
for (int x = 0; x < 32; x++)
{
buttonGrid.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Star)
});
buttonGrid.RowDefinitions.Add(new RowDefinition
{
Height = new GridLength(1, GridUnitType.Star)
});
for (int y = 0; y < 32; y++)
{
var bt = new Button();
bt.Content = x + "" + y;
Grid.SetRow(bt, x);
Grid.SetColumn(bt, y);
buttonGrid.Children.Add(bt);
bt.Click += Bt_Click;
}
}
}
private void Bt_Click(object sender, RoutedEventArgs e)
{
Button bt = (Button)sender;
bt.Background = Brushes.Black;
}
}
MainWindow.xaml
<Grid Name="buttonGrid"></Grid>
Be aware that resizing is going to be quite slow.

Set Rectangle width by Items in list C# WPF

How do I set the width of a rectangle, by dividing the number of Items in a list via a user control in C#, using WPF has to be in code behind and not using Xaml:
public partial class UserControl1 : UserControl
{
private List<Color> colours;
private int Highest;
private int Lowest;
private int Median;
public int Width {get; set;}
private Data mydata;
public Data data
{
get
{
return mydata;
}
set
{
mydata = value;
BindData();
}
}
public UserControl1()
{
colours = new List<Color>() { Colors.Red, Colors.White, Colors.Blue};
InitializeComponent();
if (Width == 0)
{
Width = 300;
}
}
private void BindData()
{
//work out rectangle width
Highest = Convert.ToInt32(mydata.Values.Max());
Lowest = Convert.ToInt32(mydata.Values.Min());
Median = Convert.ToInt32(mydata.Values.Average());
foreach (double item in mydata.Values)
{
//create rectangle of width specified
SetWidth();
}
}
private void SetWidth()
{
//divide number of items in list by total to define Width
}
private Color GetColourFromValue(int totalNumber)
{
var numOfColours = colours.Count;
if (totalNumber >= numOfColours)
{
return colours[totalNumber % numOfColours];
}
return colours[totalNumber];
}
private Color GetGradeColour(byte itemNumber, byte totalNumberItems, Color ItemColour)
{
byte multipler = (byte)(200 / totalNumberItems);
byte a = (byte)((itemNumber + 1) * multipler);
return Color.FromArgb(a, ItemColour.R, ItemColour.G, ItemColour.B);
}
private Rectangle CreateRectangle(double Value, int Width, Color ItemColor)//double value, width)
{
//create rectangle
var rectangle = new Rectangle()
{
//Fill = new SolidColorBrush(ItemColor)
};
//give rectangle width
return rectangle;
}
}
If you want a set of controls to automatically share the horizontal space of a parent UserControl then use a Grid control with columns. This is much easier than trying the calculate the widths manually.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0"/>
<Rectangle Grid.Column="1"/>
<Rectangle Grid.Column="2"/>
<Rectangle Grid.Column="3"/>
</Grid>
Code:
var grid = new Grid
{
ColumnDefinitions =
{
new ColumnDefinition(),
new ColumnDefinition(),
new ColumnDefinition(),
new ColumnDefinition()
}
};
var rectangle1 = new Rectangle { Fill = Brushes.Blue };
rectangle1.SetValue(Grid.ColumnProperty, 0);
grid.Children.Add(rectangle1);
var rectangle2 = new Rectangle { Fill = Brushes.Red };
rectangle2.SetValue(Grid.ColumnProperty, 1);
grid.Children.Add(rectangle2);
var rectangle3 = new Rectangle { Fill = Brushes.Green };
rectangle3.SetValue(Grid.ColumnProperty, 2);
grid.Children.Add(rectangle3);
var rectangle4 = new Rectangle { Fill = Brushes.Yellow };
rectangle4.SetValue(Grid.ColumnProperty, 3);
grid.Children.Add(rectangle4);

Drawing Line Arrays WPF

I'm trying to move my project from WinForms to WPF, but i couldn't succeed in this. I had a picture box, with a full of lines one after another and i could just use DrawLine(pen,point,point) in a loop. But when i tried to do this by using WPF, i couldn't menage.
This is the code snippet that i've used in WinForms :
for (x = 0; x < X_COORD_END - X_COORD_START; x += 1)
{
System.Drawing.Point point1 = new System.Drawing.Point(x, 30);
System.Drawing.Point point2 = new System.Drawing.Point(x, 60);
e.Graphics.DrawLine(myPen, point1, point2);
}
And the result was :
I've tried to use Line array on WPF, but i gave an error on canvas.Children.Add line. Now i'm trying to use collection of points, but i can't arrange points as i want to. Here is what i've tried :
private void DrawLine(Point[] points)
{
Polyline line = new Polyline();
PointCollection collection = new PointCollection();
foreach (Point p in points)
{
collection.Add(p);
}
line.Points = collection;
line.Stroke = new SolidColorBrush(Colors.Black);
line.StrokeThickness = 20;
scanCanvas.Children.Add(line);
}
for (int counter = 0; counter < 1000; counter++ )
{
points[counter] = new Point(counter, 30);
}
DrawLine(points);
Use Stackpanel for your scenario. I have used a line array, which is similar to the thing which you have done in winforms.
MainWindow.xaml
<Window x:Class="SO.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="stackGraphicsArea" Orientation="Horizontal"/>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Line[] lines = new Line[1000];
for(int i=0; i<1000;i++)
{
lines[i] = new Line();
lines[i].Stroke = new SolidColorBrush(Colors.Red);
lines[i].StrokeThickness = 5;
lines[i].X1 = 0;
lines[i].X2 = 0;
lines[i].Y1 = 30;
lines[i].Y2 = 20;
}
DrawLines(lines);
}
private void DrawLines(Line[] _lines)
{
foreach (Line _line in _lines)
{
stackGraphicsArea.Children.Add(_line);
}
}
}
Sriman Reddy has answered my question already but i think i should post my own solution too :
private void DrawLine(int x_coord_start, int y_coord_start, int x_coord_end, int thickness, Color color)
{
Random rand = new Random();
for (int x = 0; x < x_coord_end - x_coord_start; x++)
{
double newTop = rand.Next();
Line top = new Line();
top.Stroke = new SolidColorBrush(color);
top.StrokeThickness = x + 1;
top.X1 = x_coord_start + x;
top.Y1 = y_coord_start;
top.X2 = x_coord_start + x;
top.Y2 = y_coord_start + thickness;
Canvas.SetTop(top, 0);
Canvas.SetLeft(top, 0 /*x * top.Width*/);
scanCanvas.Children.Add(top);
}
}

C# WPF. How to add Ellipces dynamically into canvas?

I'm trying to add some ellipces with random positions into my canvas, but i can see them on my canvas. Progmab is compilling quite saccesfull. Code:
for (int i = 0; i < FirefliesCount; ++i)
{
Firefly CurrentFirefly = new Firefly();
CurrentFirefly.Speed = Randomer.Next(1, 3);
CurrentFirefly.Body = new Ellipse();
CurrentFirefly.Body.Margin = new Thickness(Randomer.Next(10, (int)MainCanvas.Width - 10),
Randomer.Next(10, (int)MainCanvas.Height - 10),
0, 0);
CurrentFirefly.Body.Fill = Brushes.Black;
CurrentFirefly.Body.Height = MainCanvas.Height / 4;
CurrentFirefly.Body.Width = 1.5 * CurrentFirefly.Body.Height;
MainCanvas.Children.Add(CurrentFirefly.Body);
}
And Fireflie class:
class Firefly
{
public Ellipse Body { get; set; }
public int Speed { get; set; }
}
Probably you did not set the Width and Height properties of your MainCanvas; then they have the value NaN and therefore you will not see the ellipses.
My suggestion is to use ActualWidth and ActualHeight instead and to delay the adding of the ellipses until the canvas is loaded. Here is an example:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainCanvas.Loaded += MainCanvas_Loaded;
}
void MainCanvas_Loaded(object sender, RoutedEventArgs e)
{
Init();
}
private void Init()
{
const int FirefliesCount = 100;
Random Randomer = new Random();
for (int i = 0; i < FirefliesCount; ++i)
{
Firefly CurrentFirefly = new Firefly();
CurrentFirefly.Speed = Randomer.Next(1, 3);
CurrentFirefly.Body = new Ellipse();
CurrentFirefly.Body.Margin = new Thickness(Randomer.Next(10, (int)MainCanvas.ActualWidth - 10),
Randomer.Next(10, (int)MainCanvas.ActualHeight - 10),
0, 0);
CurrentFirefly.Body.Fill = Brushes.Black;
CurrentFirefly.Body.Height = MainCanvas.ActualHeight / 4;
CurrentFirefly.Body.Width = 1.5 * CurrentFirefly.Body.Height;
MainCanvas.Children.Add(CurrentFirefly.Body);
}
}
}
The corresponding xaml file looks like this:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="MainCanvas"/>
</Window>

Painting a UniformGrid in C# using WPF

I am relatively new to C# and I'm trying to create a window with a grid of a dynamic amount of same-sized squares. The squares are then to have their color changed by a process.
I'm currently struggling to generate the grid of squares. Whenever I run the application it seems to be going crazy on resources and I'm not sure why.
The code I am using follows:
private void Window_Loaded(object sender, RoutedEventArgs e) {
//create a blue brush
SolidColorBrush vBrush = new SolidColorBrush(Colors.Blue);
//set the columns and rows to 100
cellularGrid.Columns = mCellAutomaton.GAME_COLUMNS;
cellularGrid.Rows = mCellAutomaton.GAME_ROWS;
//change the background of the cellular grid to yellow
cellularGrid.Background = Brushes.Yellow;
//create 100*100 blue rectangles to fill the cellular grid
for (int i = 0; i < mCellAutomaton.GAME_COLUMNS; i++) {
for (int j = 0; j < mCellAutomaton.GAME_ROWS; j++) {
Rectangle vRectangle = new Rectangle();
vRectangle.Width = 10;
vRectangle.Height = 10;
vRectangle.Fill = vBrush;
cellularGrid.Children.Add(vRectangle);
}
}
}
Is this even the approach I want to take if I want a modifiable grid of squares?
Thanks for any help,
Jason
this seems to perform pretty fast
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="350" Name="UI">
<Grid Name="Test">
<UniformGrid Name="UniGrid" />
</Grid>
</Window>
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
AddRows(new Size(10, 10));
}
private void AddRows(Size recSize)
{
UniGrid.Columns = (int)(UniGrid.ActualWidth / recSize.Width);
UniGrid.Rows = (int)(UniGrid.ActualHeight / recSize.Height);
for (int i = 0; i < UniGrid.Columns * UniGrid.Rows; i++)
{
UniGrid.Children.Add(new Rectangle { Fill = new SolidColorBrush(Colors.Yellow), Margin = new Thickness(1) });
}
}
}

Categories

Resources