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

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>

Related

WPF Grid white stripes

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 = ""
});
}
}

How to add a proceduaraly generated billboard to helix 3D

I have a set of procedural images that I would like to add as billboards to my helix 3D application.
Currently my application looks as following:
public partial class _3DControl
{
HelixViewport3D hVp3D;
public _3DControl()
{
InitializeComponent();
createView();
}
public void createView()
{
hVp3D = new HelixViewport3D();
var lights = new SunLight();
lights.Altitude=40;
lights.Ambient=0.4;
this.Content = hVp3D;
hVp3D.Children.Add(lights);
this.Show();
}
public void UploadBillboard(BitmapImage im, System.Windows.Media.Media3D.Point3D position,double width,double height)
{
//create material
var mat = MaterialHelper.CreateImageMaterial(im, 0);
var bboard = new BillboardVisual3D();
bboard.Material = mat;
//set coordinates
bboard.Position = position;
bboard.Width = width;
bboard.Height = height;
//add the billboard
hVp3D.Children.Add(bboard);
}
However when I call the function to add a billboard:
HelixLinker.GetHelix().UploadBillboard(((Bitmap)e).bitmapToBitmapImage(),
new System.Windows.Media.Media3D.Point3D(0, 0, 0), 100, 100);
Then I see nothing being added, any idea what I' m doing wrong?
I also tried with the RectangleVisual3D class.
public void UploadRect(BitmapImage im, System.Windows.Media.Media3D.Point3D position, double width, double height)
{
var mat = MaterialHelper.CreateImageMaterial(im, 0);
var bboard = new RectangleVisual3D ();
bboard.Material = mat;
bboard.Width = width;
hVp3D.Children.Add(bboard);
}
Which if execuded in the same way results in a (promising) image however in this case the material appears not to be properly set.
Note: I hope that the BillboardVisual3D is the right class, I'm working on something that will allow me to put image "on the floor" so to speak, I want to have flat images that don't have a depth and allow for transparancy.
Why do you set the Opacity to 0? Then you wont see anything.
Try this:
//create material
var mat = MaterialHelper.CreateImageMaterial(im);
See the documentation
Edit:
Sorry, my bad with the string. But this ist working for me:
Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CreateBilboard();
}
private void CreateBilboard()
{
BitmapImage im = new BitmapImage(new System.Uri(#"C:\Users\Public\Pictures\Sample Pictures\Lighthouse.jpg"));
var mat = MaterialHelper.CreateImageMaterial(im, 1);
var bboard = new BillboardVisual3D();
bboard.Material = mat;
var position = new System.Windows.Media.Media3D.Point3D(0, 0, 0);
var width = 100;
var height = 100;
//set coordinates
bboard.Position = position;
bboard.Width = width;
bboard.Height = height;
//add the billboard
viewPort.Children.Add(bboard);
}
}
XAML:
<Window x:Class="BillboardImageMaterialDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ht="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf"
Title="BillboardImageMaterialDemo" Height="480" Width="640">
<Grid>
<ht:HelixViewport3D x:Name="viewPort" ZoomExtentsWhenLoaded="True">
<!-- Remember to add some lights -->
<ht:SunLight/>
</ht:HelixViewport3D>
</Grid>
</Window>
Result:

Oxyplot distance between ticks

How to decrease distance between ticks? I want to place candles more closely.
And i cannot find any property in LinearAxis XAxis that respond for distance.
Code:
namespace WpfApplication20
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new PlotClass();
}
}
public class PlotClass
{
public PlotModel PlotModel { get; set; }
public PlotClass()
{
Random rnd = new Random();
PlotModel = new PlotModel();
LineSeries LS = new LineSeries();
LinearAxis XAxis = new LinearAxis
{
Position = AxisPosition.Bottom,
MinorStep=1,
MajorStep=1
};
LinearAxis YAxis = new LinearAxis()
{
Position = AxisPosition.Left
};
for (int i=0;i<10;i++)
{
LS.Points.Add(new DataPoint(i,rnd.Next(1,10)));
}
PlotModel.Axes.Add(YAxis);
PlotModel.Axes.Add(XAxis);
PlotModel.Series.Add(LS);
ChangeToCandles();
WhatTypeOfSeries();
}
public void ChangeToCandles()
{
Random rnd = new Random();
PlotModel.Series.Clear();
CandleStickSeries CSS = new CandleStickSeries();
for (int i = 0; i < 10;i++ )
{
CSS.Items.Add(new HighLowItem { X = i, Close = rnd.NextDouble(), High = rnd.NextDouble(), Low = rnd.NextDouble(), Open = rnd.NextDouble() });
}
PlotModel.Series.Add(CSS);
}
public void WhatTypeOfSeries()
{
var temp = PlotModel.Series[0].GetType();
Console.WriteLine(temp);
}
}
}
xaml:
<Grid>
<oxy:Plot Model="{Binding PlotModel}"/>
</Grid>
Try zooming:
XAxis.Zoom(-5, 15);
EDIT>>>>
You have a for loop from 0 to 10, you just have to add some adjust values. For that limits for being more generic:
int lowerIndex = 0;
int upperIndex = 10;
int zoomValue = 5;
for (int i=lowerIndex;i<upperIndex;i++)
{
LS.Points.Add(new DataPoint(i,rnd.Next(1,10)));
}
XAxis.Zoom(lowerIndex-zoomValue, upperIndex+zoomValue);
Try to play with CandleStickSeries.CandleWidth property:
If it is set to 1, then there will be no space between candles.
If it is set to value > 1, then candles will overlap.
If it is set to value < 1, then there will be a gap between candles. The smaller value, the bigger gap.

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);
}
}

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