I'm not sure if I'm going about this right. What I need is after the user creates all of their lines, could be 1 could be 10. I can calculate the length of those lines, take the zone that line appeared in and add it to a list.
So in the end you have for example
Length Location
2 1
4 2
3 1
8 1
Afterwards I will be adding this data to their respective columns on the oracle server. Is a list appropriate? I get an out of bounds error currently on Zone1 and distfinal. If I just do one line then I get a length calc but an out of bound error on Zone1
List<string> Zone1 = new List<string>();
private Point p1, p2;
List<Point> p1List = new List<Point>();
List<Point> p2List = new List<Point>();
Dictionary<string, int> Void = new Dictionary<string, int>();
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button.Equals(MouseButtons.Left))
{
if (p1.X == 0)
{
p1.X = e.X;
p1.Y = e.Y;
var color = zoneMap1.GetPixel(e.X, e.Y);
if (color == Color.FromArgb(0, 0, 255))
{
//MessageBox.Show("Zone 1");
Zone1.Add("1");
}
else if (color == Color.FromArgb(0, 255, 0))
{
//MessageBox.Show("Zone 2");
Zone1.Add("2");
}
}
else
{
p2.X = e.X;
p2.Y = e.Y;
p1List.Add(p1);
p2List.Add(p2);
Invalidate();
pictureBox1.Refresh();
p1.X = 0;
}
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (var p = new Pen(Color.Red, 5))
{
for (int x = 0; x < p1List.Count; x++)
{
e.Graphics.DrawLine(p, p1List[x], p2List[x]);
}
}
}
With what I have here, assuming I am going about this correctly, the errors occur with Void.Add(Zone1[i], distfinal);
Ultimately I'd like to just create all the lines. Then use the below button to create the example I gave at the top.
private void btnCalc_Click(object sender, EventArgs e)
{
for (int i = 0; i < p1List.Count; i++)
{
if (p1List.Count != 0 && p2List.Count != 0)
{
dist = (Convert.ToInt32(Math.Pow(p1.X - p1.Y, 2) + Math.Pow(p2.X - p2.Y, 2)));
int distfinal = (dist % 32);
Void.Add(Zone1[i], distfinal);
}
else
{
MessageBox.Show("You must first create a line");
}
}
}
Well, learned Tuple :)
This fixed it.
var list = new List<Tuple<string, int>>();
list.Add(new Tuple<string, int>(Zone1[i], distfinal));
Related
The method genereer ("generate") draws a Bitmap image of a Mandelbrot. It has a variable schaal ("scale") which makes the Bitmap zoom in on the image with a certain factor. The standard value for this is 0.01, as declared above in the partial class Form1.
I have a textBox3 in the GUI, and I want to be able to type a new value in this textBox3, click on the button and draw a new image based on the scale.
I've written a method called Lees ("read"), which parses a double from textBox3. I've put this method in the Button1_MouseClick method, as well as the genereer method to draw a new image upon button click. I've also put the genereer method in the Form1_Shown method.
However, this doesn't seem to be working. When I click on the button, no matter what the value is, I get a white dot in the middle of the screen.
public partial class Form1 : Form
{
public double waardeX, waardeY, schaal = 0.01;
public int maxIteraties;
public Form1()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
Genereer();
}
public void Lees()
{
schaal = double.Parse(textBox3.Text);
}
private void Genereer()
{
double max = 100;
Bitmap bitmap = new Bitmap(Figuur.Width, Figuur.Height);
for (int x = 0; x < Figuur.Width; x++)
{
for (int y = 0; y < Figuur.Height; y++)
{
//double a = (double)(x - (Figuur.Width / 2)) / (double)(Figuur.Width / 4);
//double b = (double)(y - (Figuur.Height / 2)) / (double)(Figuur.Height / 4);
double a = (double)(x - (Figuur.Width / 2)) * (double)(schaal);
double b = (double)(y - (Figuur.Height /2)) * (double)(schaal);
Mandelgetal getal = new Mandelgetal(a, b);
Mandelgetal waarde = new Mandelgetal(0, 0);
int i = 0;
while (i < max)
{
//i++; //v1
waarde.Vermenigvuldig();
waarde.Toevoegen(getal);
if (waarde.Wortel() > 2.0)
{
break;
}
else
{
if (i % 2.0 == 0.0)
{
bitmap.SetPixel(x, y, Color.White);
i++; //v2
}
else
{
bitmap.SetPixel(x, y, Color.Black);
i++; //v2
}
}
}
if((a*a + b*b) > 4)
{
bitmap.SetPixel(x, y, Color.Black);
}
Figuur.Image = bitmap;
}
}
}
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
Lees();
Genereer();
this.Invalidate();
}
}
}
I'm trying to draw an axis table (x-y) in WPF from code-behind; and I want to give it drag and drop option which can see more of the axis table.
I had created static axis but I don't know how to create a dynamic one?
Can anybody help me with this stuff ?
Thanks.
for (int i = 10; i < 400; i+=10)
{
Line a = new Line();
a.X1 = 0;
a.Y1 = i;
a.X2 = canGraph.Width;
a.Y2 = a.Y1;
a.Stroke = System.Windows.Media.Brushes.Black;
a.StrokeThickness = 0.5;
canGraph.Children.Add(a);
Line b = new Line();
b.X1 = i;
b.Y1 = 0;
b.X2 = i;
b.Y2 = canGraph.Height;
b.Stroke = System.Windows.Media.Brushes.Black;
b.StrokeThickness = 0.5;
canGraph.Children.Add(b);
if (i % 50 == 0)
{
a.StrokeThickness = 1;
b.StrokeThickness = 1;
}
if (i == 200)
{
a.StrokeThickness = 2;
b.StrokeThickness = 2;
}
}
This should get you started. Add event handler(s) to your main axis and canGraph -
...
if (i == 200)
{
a.StrokeThickness = 2;
b.StrokeThickness = 2;
a.MouseLeftButtonDown += A_MouseLeftButtonDown;
}
}
canGraph.MouseLeftButtonUp += CanGraph_MouseLeftButtonUp;
canGraph.MouseMove += CanGraph_MouseMove;
Add following methods -
Line _selectedAxis = null;
private void CanGraph_MouseMove(object sender, MouseEventArgs e)
{
if (_selectedAxis != null)
{
var line = _selectedAxis;
var pos = e.GetPosition(line);
textBlock.Text = $"({pos.X}, {pos.Y})";
line.Y1 = pos.Y;
line.Y2 = pos.Y;
}
}
private void CanGraph_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_selectedAxis = null;
}
private void A_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var line = sender as Line;
_selectedAxis = line;
}
Now hold you main horizontal axis and drag it.
You can do the same for vertical axis as well.
For Zooming
Initialize canGraph.RenderTransform with ScaleTransform and subscribe to MouseWheel event. Note RenderTransformOrigin is set to (0.5, 0.5) to zoom from center instead of top left (default) -
canGraph.RenderTransformOrigin = new Point(0.5, 0.5);
canGraph.RenderTransform = new ScaleTransform();
canGraph.MouseWheel += CanGraph_MouseWheel;
And the function -
private void CanGraph_MouseWheel(object sender, MouseWheelEventArgs e)
{
var transform = canGraph.RenderTransform as ScaleTransform;
var factor = transform.ScaleX;
factor += (e.Delta > 0 ? 1 : (factor == 1 ? 0 : -1));
transform.ScaleX = factor;
transform.ScaleY = factor;
}
I'm guessing you have added Line type object to draw axes, then gave it to window content.
Then just add events, like MouseLeftButtonDown event, or MouseMove event.Add appropriate methods.
Change your object positions on MouseMove event, like:
(For a certain line)
private void MouseMoveMethod(object sender, MouseEventArgs e)
{
var obj = sender as Line;
obj.X1 = e.GetPosition(this).X; //Line start x coordinate
obj.Y1 = e.GetPosition(this).Y; //Line start y coordinate
...
}
I'm giving my panels inside another panel (this panel is in a usercontrol) a fixed location and a maximum size that changes with the size of the panel there in. Neither the resize or location works properly. The resize does happen but its to quickly. The location is fine if you only have 1 pinpanel for output and input. When you have more then 1 the locations are fixed but you need to resize the panel to resize to see the other panels. Could you point me in the right direction if you see the problem?
I have a panel drawPanel in this case that i use as a sort of background for the usercontrol. Inside this drawPanel i'm placing pinpanels. I want these pinpanels to resize with the usercontrol and give them a fixed location
private void OnClickPinPanel(object source, EventArgs e)
{
if (source is PinPanel p)
{
int index;
if ((index = Array.IndexOf(inputPins, p)) >= 0)
{
ClickedPinPanel?.Invoke(index, true);
}
else
{
ClickedPinPanel?.Invoke(Array.IndexOf(outputPins, p), false);
}
}
//else log here
}
private void CreatePinPanels(bool isInput)
{
int x = 0;
int y = -(int)(this.Width * 0.05)/2;
if (isInput)
{
for (int i = 0; i < inputPins.Length; i++)
{
y += (i + 1) * (this.Height / inputPins.Length + 1);
inputPins[i] = new PinPanel()
{
Location = new Point(x, y),
Size = new Size((int)(this.Width * 0.05), (int)(this.Width * 0.05)),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right,
};
inputPins[i].Click += OnClickPinPanel;
}
}
else
{
x += this.Width - (int)(this.Width * 0.1);
for (int i = 0; i < outputPins.Length; i++)
{
y += (i + 1) * (this.Height / inputPins.Length+1);
outputPins[i] = new PinPanel()
{
Size = new Size((int)(this.Width * 0.1), (int)(this.Width * 0.1)),
Location = new Point(x, y),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right
};
outputPins[i].Click += OnClickPinPanel;
}
}
}
The result i get now is that the pinpanels get a fixed location but when you have more then 1 pinpanel, the location is wrong its like if he thinks that the usercontrol is bigger then it is Reality. In order to see all the pins i have to resize and get this After resize
I want it to look like this
expectations
Try something like this out.
Here is my test rig:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
numericUpDown1.Value = someChip1.NumberInputPins;
numericUpDown2.Value = someChip1.NumberOutputPins;
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
someChip1.NumberInputPins = (int)numericUpDown1.Value;
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
someChip1.NumberOutputPins = (int)numericUpDown2.Value;
}
}
Sample chip with 5 inputs and 3 outputs:
Here is my PinPanel UserControl (just draws an ellipse/pin the size of the control):
public partial class PinPanel : UserControl
{
public PinPanel()
{
InitializeComponent();
}
private void PinPanel_Paint(object sender, PaintEventArgs e)
{
Rectangle rc = new Rectangle(new Point(0, 0), new Size(this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1));
e.Graphics.DrawEllipse(Pens.Black, rc);
}
private void PinPanel_SizeChanged(object sender, EventArgs e)
{
this.Refresh();
}
}
And finally, my SomeChip UserControl:
public partial class SomeChip : UserControl
{
public event PinPanelClick ClickedPinPanel;
public delegate void PinPanelClick(int index, bool input);
private PinPanel[] inputPins;
private PinPanel[] outputPins;
private int _NumberInputPins = 2;
public int NumberInputPins
{
get {
return _NumberInputPins;
}
set
{
if (value > 0 && value != _NumberInputPins)
{
_NumberInputPins = value;
CreatePinPanels();
this.Refresh();
}
}
}
private int _NumberOutputPins = 1;
public int NumberOutputPins
{
get
{
return _NumberOutputPins;
}
set
{
if (value > 0 && value != _NumberOutputPins)
{
_NumberOutputPins = value;
CreatePinPanels();
this.Refresh();
}
}
}
public SomeChip()
{
InitializeComponent();
}
private void SomeChip_Load(object sender, EventArgs e)
{
CreatePinPanels();
RepositionPins();
}
private void SomeChip_SizeChanged(object sender, EventArgs e)
{
this.Refresh();
}
private void SomeChip_Paint(object sender, PaintEventArgs e)
{
int PinHeight;
// draw the input pin runs
if (inputPins != null)
{
PinHeight = (int)((double)this.Height / (double)_NumberInputPins);
for (int i = 0; i < NumberInputPins; i++)
{
int Y = (i * PinHeight) + (PinHeight / 2);
e.Graphics.DrawLine(Pens.Black, 0, Y, this.Width / 4, Y);
}
}
// draw the output pin runs
if (outputPins != null)
{
PinHeight = (int)((double)this.Height / (double)_NumberOutputPins);
for (int i = 0; i < NumberOutputPins; i++)
{
int Y = (i * PinHeight) + (PinHeight / 2);
e.Graphics.DrawLine(Pens.Black, this.Width - this.Width / 4, Y, this.Width, Y);
}
}
//draw the chip itself (takes up 50% of the width of the UserControl)
Rectangle rc = new Rectangle(new Point(this.Width / 4, 0), new Size(this.Width / 2, this.Height - 1));
using (SolidBrush sb = new SolidBrush(this.BackColor))
{
e.Graphics.FillRectangle(sb, rc);
}
e.Graphics.DrawRectangle(Pens.Black, rc);
RepositionPins();
}
private void CreatePinPanels()
{
if (inputPins != null)
{
for (int i = 0; i < inputPins.Length; i++)
{
if (inputPins[i] != null && !inputPins[i].IsDisposed)
{
inputPins[i].Dispose();
}
}
}
inputPins = new PinPanel[_NumberInputPins];
for (int i = 0; i < inputPins.Length; i++)
{
inputPins[i] = new PinPanel();
inputPins[i].Click += OnClickPinPanel;
this.Controls.Add(inputPins[i]);
}
if (outputPins != null)
{
for (int i = 0; i < outputPins.Length; i++)
{
if (outputPins[i] != null && !outputPins[i].IsDisposed)
{
outputPins[i].Dispose();
}
}
}
outputPins = new PinPanel[_NumberOutputPins];
for (int i = 0; i < outputPins.Length; i++)
{
outputPins[i] = new PinPanel();
outputPins[i].Click += OnClickPinPanel;
this.Controls.Add(outputPins[i]);
}
}
private void OnClickPinPanel(object sender, EventArgs e)
{
PinPanel p = (PinPanel)sender;
if (inputPins.Contains(p))
{
ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), true);
}
else if (outputPins.Contains(p))
{
ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), false);
}
}
private void RepositionPins()
{
int PinRowHeight, PinHeight;
if (inputPins != null)
{
PinRowHeight = (int)((double)this.Height / (double)_NumberInputPins);
PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
for (int i = 0; i < inputPins.Length; i++)
{
if (inputPins[i] != null && !inputPins[i].IsDisposed)
{
inputPins[i].SetBounds(0, (int)((i * PinRowHeight) + (PinRowHeight /2 ) - (PinHeight / 2)), PinHeight, PinHeight);
}
}
}
if (outputPins != null)
{
PinRowHeight = (int)((double)this.Height / (double)_NumberOutputPins);
PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
for (int i = 0; i < outputPins.Length; i++)
{
if (outputPins[i] != null && !outputPins[i].IsDisposed)
{
outputPins[i].SetBounds(this.Width - PinHeight, (int)((i * PinRowHeight) + (PinRowHeight / 2) - (PinHeight / 2)), PinHeight, PinHeight);
}
}
}
}
}
I am developing a GIS application. I want to open a particular form with drawn lines. The form which will open contains a textbox which is showing the length of the line. I am able to select the line. I am able to get the length of the line.
I want to link the form with each line. and the same form should be displayed whenever that line is selected. How can i do it?
should i go for serialization? or is there any good solution?
I know this is GIS related thing, but its more like a C# problem.
Code:
private bool amDigitizing = false;
//Coordiant
private List<DotSpatial.Topology.Coordinate> myDigitizedPoints = new List<DotSpatial.Topology.Coordinate>();
private List<DotSpatial.Topology.Coordinate> myExtractedPoints = new List<DotSpatial.Topology.Coordinate>();
// DEM Layer
private DotSpatial.Controls.MapRasterLayer demLyr;
// Line Layer
private DotSpatial.Controls.MapLineLayer LineLyr;
FormTableEditor ft = new FormTableEditor();
public Form1()
{
InitializeComponent();
appManager1.LoadExtensions();
appManager1.CompositionContainer.ComposeParts(toolManager1);
}
private void map1_MouseMove(object sender, MouseEventArgs e)
{
Coordinate c_mouse = map1.PixelToProj(new System.Drawing.Point(e.X, e.Y));
Xstrip.Text = "X:" + Convert.ToString(c_mouse.X);
Ystrip.Text = "Y:" + Convert.ToString(c_mouse.Y);
}
private void btnDraw_Click(object sender, EventArgs e)
{
try
{
//map1.Layers.Remove(LineLyr);
}
catch
{
// do nothing
}
// Start a Drawing
MessageBox.Show(" Click on the map to draw, double click to stop drawing");
amDigitizing = true;
myDigitizedPoints = new List<DotSpatial.Topology.Coordinate>();
map1.FunctionMode = DotSpatial.Controls.FunctionMode.None;
}
private void map1_MouseClick_1(object sender, MouseEventArgs e)
{
// digitizing
if (amDigitizing == true)
{
DotSpatial.Topology.Coordinate c = new DotSpatial.Topology.Coordinate();
System.Drawing.Point p = new System.Drawing.Point();
p.X = e.X;
p.Y = e.Y;
c = map1.PixelToProj(p);
//double[] s = c.ToArray();
//StartX = s[0];
//StartY = s[1];
myDigitizedPoints.Add(c);
}
}
int NoOfMines = 0;
private void map1_MouseDoubleClick_1(object sender, MouseEventArgs e)
{
// Double click ends digitizing
if (amDigitizing == true)
{
DotSpatial.Topology.Coordinate c = new DotSpatial.Topology.Coordinate();
System.Drawing.Point p = new System.Drawing.Point();
p.X = e.X;
p.Y = e.Y;
c = map1.PixelToProj(p);
myDigitizedPoints.Add(c);
//double[] s = c.ToArray();
//EndX = s[0];
//EndY = s[1];
amDigitizing = false;
DotSpatial.Data.Feature f = new DotSpatial.Data.Feature(DotSpatial.Topology.FeatureType.Line, myDigitizedPoints);
DotSpatial.Data.FeatureSet fs = new DotSpatial.Data.FeatureSet();
fs.AddFeature(f);
NoOfMines = NoOfMines +1 ;
fs.Projection = map1.Projection;
for (int i = 0; i < NoOfMines; i++)
{
fs.Name = "Mine Field" + NoOfMines.ToString();
}
//fs.SaveAs(GraphicsPathExt, true);
//LineLyr = (DotSpatial.Controls.MapLineLayer)map1.AddLayer(GraphicsPathExt);
LineLyr = (MapLineLayer)map1.Layers.Add(fs);
}
}
// Length of the line
private void mnuThin_Click(object sender, EventArgs e)
{
LineLyr.Symbolizer.SetFillColor(Color.Red);
LineLyr.Symbolizer.SetWidth(5.0);
LineLyr.Symbolizer.SetOutline(Color.White, 1.0);
map1.Refresh();
IRaster r = (IRaster)map1.Layers[0].DataSet;
IFeatureSet fs = LineLyr.DataSet;
int np = 0;
try
{
foreach (IFeature f in fs.Features)
{
np += f.Coordinates.Count * 100;
}
}
catch
{
}
double[] plotX = new double[np - 99];
double[] plotY = new double[np - 99];
double x1= 0, y1 = 0, x2 = 0 , y2 = 0 , dx = 0 , dy = 0, newx = 0, newy = 0;
double z = 0;
double TotalLength = 0.0;
int i = 0;
double[] Slope = new double[np / 100];
foreach (IFeature f in fs.Features)
{
foreach (DotSpatial.Topology.Coordinate c in f.Coordinates)
{
x2 = c.X;
y2 = c.Y;
if (i > 0)
{
dx = (x2 - x1) / 100;
dy = (y2 - y1) / 100;
newx = x1;
newy = y1;
for (int j = 0; j < 100; j++)
{
TotalLength += Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
z = demLyr.DataSet.GetNearestValue(newx, newy);
i += 1;
}
}
x1 = x2;
y1 = y2;
if (i == 0)
{
z = demLyr.DataSet.GetNearestValue(newx, newy);
i += 1;
x1 = x2;
y1 = y2;
}
}
}
//Length of the line
ft.textBox1.Text = TotalLength.ToString();
}
//Selection of layer
private void customizeToolStripMenuItem_Click(object sender, EventArgs e)
{
IMapLayer layerSelect = appManager1.Map.Layers.SelectedLayer;
if (layerSelect == LineLyr)
{
ft.Show();
}
}
As Peter duniho mentioned in the comments of selection change event.
i used that approach to link the form.
DrawObject o = new DrawObject;
Form1 f = new Form1(o);
LegendItem li = new LegendItem();
if (li.IsSelected == true)
{
f.Textbox1.Text = frontage.ToString();
f.show();
}
I am recreating the classic game Reversi using c# in order to improve my skills at programming
but I have a problem when I check the colors. So far I have managed to revers colors from left and from top but it doesn't work correctly it only reverses the colors when I hit the last square on the board.
Any help would be much appreciated
Here is an image that may explain what I mean (the code is below) mean
The code that I have:
namespace praprevers
{
public partial class Form1 : Form
{
private Button[,] squares;
//private Button[,] r0;
public Form1()
{
InitializeComponent();
squares = new Button[4, 4];
squares = new Button[,] {
{btn_0_0, btn_0_1, btn_0_2, btn_0_3},
{btn_1_0, btn_1_1, btn_1_2, btn_1_3},
{btn_2_0, btn_2_1, btn_2_2, btn_2_3},
{btn_3_0, btn_3_1, btn_3_2, btn_3_3}
};
}
int _turn = 0;
private void DrawColor(object sender, EventArgs e)
{
Button b = sender as Button;
string[] btnData = b.Name.Split('_');
int x = int.Parse(btnData[1]);
int y = int.Parse(btnData[2]);
//check for possible combinations
int top = x - 3;
int botton = x +3;
int left = y - 3;
int right = y + 3;
for (int l = 0; l < 4; ++l)
{
if (top >= 0 && squares[top, y].BackColor == Color.Black)
{
squares[top + l, y].BackColor = Color.Black;
}
else if (left >= 0 && squares[x, left].BackColor == Color.Black)
{
squares[x, left + l].BackColor = Color.Black;
}
}
if (_turn == 0)
{
_turn = 1;
b.BackColor = Color.Black;
}
else
{
_turn = 0;
b.BackColor = Color.Red;
}
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (Button sqrr in squares)
{
sqrr.Click += new System.EventHandler(this.DrawColor);
}
}
}
}