Drag and Drop dynamically generated images [C#/Windows Store App] - c#

i have dynamically generated images. if i click last added image it dragging normally, but when i click to other image and tried to drag it, last added image dragging again.
here is my codes
void setDynamicImages()
{
for (int i = 0; i < 10; i++)
{
RectMeyve = new Rectangle();
IMG_meyve = new Image();
IMG_meyve.Height = 36 * ratioHeight;
IMG_meyve.Width = 51 * ratioWidth;
randMeyveCesit = Rand.Next(5);
IMG_meyve.Source = new BitmapImage(new Uri("ms-appx:///Assets/Sayfa10/dusen_meyveler/cilek_0" + (randMeyveCesit + 1) + ".png"));
IMG_meyve.Tag =randMeyveTur;
pressedIMGTag =randMeyveTur;
RectMeyve.Fill = new SolidColorBrush(Colors.Aqua);
RectMeyve.Height = IMG_meyve.ActualHeight;
RectMeyve.Width = IMG_meyve.Width;
Canvas.SetLeft(RectMeyve, Canvas.GetLeft(IMG_meyve));
Canvas.SetTop(RectMeyve, Canvas.GetTop(IMG_meyve));
RectMeyve.Opacity = 0.6;
RectMeyve.IsHitTestVisible = false;
IMG_meyve.ActualWidth, IMG_meyve.ActualHeight);
this.canvasMeyveleriSayalim.Children.Add(IMG_meyve);
this.canvasMeyveleriSayalim.Children.Add(RectMeyve);
IMG_meyve.PointerPressed += IMG_meyve_PointerPressed;
IMG_meyve.PointerReleased += IMG_meyve_PointerReleased;
}
}
private void IMG_meyve_PointerPressed(object sender, PointerRoutedEventArgs e)
{
isHoldMeyve = true;
positionWithinImage = e.GetCurrentPoint(sender as Image).Position;
meyveX = e.GetCurrentPoint(IMG_meyve).Position.X;
meyveY = e.GetCurrentPoint(IMG_meyve).Position.Y;
}
private void canvasSayfa10_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (isHoldMeyve)
{
if (Convert.ToInt32(IMG_meyve.Tag) == pressedIMGTag) //this part useless
{
PointerPoint pt1 = e.GetCurrentPoint(canvasMeyveleriSayalim);
Canvas.SetLeft(IMG_meyve, pt1.Position.X - meyveX);
Canvas.SetTop(IMG_meyve, pt1.Position.Y - meyveY);
}
}
}
sorry for my english.
where is my mistake.

Related

How to access to a specific PictureBox.EventHandler that was created programmatically?

I am making a Scorebar from 1-10 where every number is one picture of a small grey cube.
Like this:
🟩🟩🟩🟩🟩⬛⬛⬛⬛⬛ (This would be a score of 5)
Now I want to change the cube images to green ones, when the MouseDown Event is triggered, but I don't know who to tell the program.
Pic of Scorebar
private void BtnDebug_Click(object sender, EventArgs e)
{
int xPos = 200;
int yPos = 100;
PictureBox[] ScoreGameplay = new PictureBox[100];
for (int i = 0; i < 10; i++)
{
ScoreGameplay[i] = new PictureBox();
ScoreGameplay[i].Name = "ScoreGameplay" + i;
ScoreGameplay[i].Size = new Size(18, 18);
ScoreGameplay[i].Location = new Point(xPos, yPos);
ScoreGameplay[i].Image = Image.FromFile(#"img\icons\score_empty.png");
ScoreGameplay[i].MouseEnter += new EventHandler(Score_MouseEnter);
ScoreGameplay[i].MouseLeave += new EventHandler(Score_MouseLeave);
ScoreGameplay[i].MouseDown += new MouseEventHandler(Score_MouseDown);
this.Controls.Add(ScoreGameplay[i]);
xPos += 18;
}
This part works without an issue, but here we go:
private void Score_MouseDown(object sender, EventArgs e)
{
if (sender is PictureBox pBox)
{
// ???
}
}
How do I tell know which Index of the Array in BtnDebug_Click has triggered the MouseDown?
For example:
The 7th PictureBox has been clicked; now I want to change the images from PictureBoxes 1-7 to the green ones.
Anyone has a smart solution for this?
Simply you can do that
private void BtnDebug_Click(object sender, EventArgs e)
{
int xPos = 200;
int yPos = 100;
PictureBox[] ScoreGameplay = new PictureBox[100];
for (int i = 0; i < 10; i++)
{
ScoreGameplay[i] = new PictureBox();
ScoreGameplay[i].Name = $"ScoreGameplay{i}";
ScoreGameplay[i].Size = new Size(18, 18);
ScoreGameplay[i].Location = new Point(xPos, yPos);
ScoreGameplay[i].Image = Image.FromFile(#"img\icons\score_empty.png");
ScoreGameplay[i].MouseEnter += new EventHandler(Score_MouseEnter);
ScoreGameplay[i].MouseLeave += new EventHandler(Score_MouseLeave);
ScoreGameplay[i].MouseDown += new MouseEventHandler(Score_MouseDown);
this.Controls.Add(ScoreGameplay[i]);
xPos += 18;
}
}
and in Score_MouseDown
private void Score_MouseDown(object sender, EventArgs e)
{
string imageName = ((PictureBox)sender).Name; // get the name of the clicked image
string imageIndex = imageName.Substring(13); // get the text after 13 chars
}

c# Dynamically creating an EventHandler in a loop

I am trying to dynamically create an array of images on a form. THe images are rendering okay, but I cannot work out how to create the eventHandlers.
pictureBox.Click += new System.EventHandler(this.pictureBox);
This line is causing be problems.
private void frmBorderlessMain_Load(object sender, EventArgs e)
{
int top = 10;
int left = 10;
int width = 200;
int height = 150;
var uutNames = MyObject.GetNames().ToArray();
var uutImages = MyObject.GetImages().ToArray();
for (int i = 0; i < uutNames.Length; i++)
{
System.Windows.Forms.PictureBox pictureBox = new System.Windows.Forms.PictureBox();
Image newImage = Image.FromFile(uutImages[i]+".png");
pictureBox.Image = ((System.Drawing.Image)(newImage));
pictureBox.Location = new System.Drawing.Point(left, top);
pictureBox.Name = "pictureBox"+i;
pictureBox.Size = new System.Drawing.Size(200, 150);
pictureBox.SizeMode =
System.Windows.Forms.PictureBoxSizeMode.Zoom;
pictureBox.TabIndex = i;
pictureBox.TabStop = false;
pictureBox.Click += new System.EventHandler(this.pictureBox);
this.tabPage1.Controls.Add(pictureBox);
left += width + 10;
if ( (i > 0 ) && (i % 3) == 0)
{
top += height + 10;
left = 10;
}
}
}
Additional Info:
Upon clicking the image I would like a new form to open displaying details about the entity that was clicked. It will be the same form, but will be loaded with data depending on which image was clicked on.
pictureBox.Click += new System.EventHandler(this.pictureBox);
That is not how event handlers are used.
Lambda:
pictureBox.Click += (sender, eventArgs) => Console.WriteLine("HELP I WAS CLICKED OMG");
Or with a function:
pictureBox.Click += PictureBox_Click;
....
private void PictureBox_Click(object sender, EventArgs e)
{
Console.WriteLine("Stop clicking me >:(");
}

How to draw moving axis table

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
...
}

C# DataGridView

I have been tasked with creating a somewhat hierarchical datagridview for my company. I heavily modified one from Syed Shanu that is posted here https://www.codeproject.com/Articles/848637/Nested-DataGridView-in-windows-forms-csharp. I'm almost done (data loads properly, etc.), however I cannot for the life of me figure out how to get the detail grid to move when I scroll. It's a drawn on rectangle and I'm looking for a way to somehow bind it to the master grid so it scrolls up and down with the regular grid. Any help would be appreciated. Here is the code that draws the rectangle:
private void masterDGVs_CellContentClick_Event(object sender, DataGridViewCellEventArgs e)
{
DataGridViewImageColumn cols = (DataGridViewImageColumn)MasterDGVs.Columns[0];
MasterDGVs.Rows[e.RowIndex].Cells[0].Value = Image.FromFile(#"expand.png");
if (e.ColumnIndex == gridColumnIndex)
{
if (ImageName == #"expand.png")
{
DetailDGVs.Visible = true;
ImageName = #"toggle.png";
MasterDGVs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Image.FromFile(ImageName);
String FilterExpression = MasterDGVs.Rows[e.RowIndex].Cells[FilterColumnName].Value.ToString();
MasterDGVs.Controls.Add(DetailDGVs);
Rectangle DGVRectangle = MasterDGVs.GetCellDisplayRectangle(1, e.RowIndex, true);
DetailDGVs.Size = new Size(MasterDGVs.Width - 48, DetailDGVs.PreferredSize.Height - 16);
DetailDGVs.Location = new Point(DGVRectangle.X, DGVRectangle.Y + 20);
DataView detailView = new DataView(DetailGridDT);
detailView.RowFilter = FilterColumnName + " = '" + FilterExpression + "'";
foreach (DataGridViewRow row in DetailDGVs.Rows)
{
if (row.Cells[5].Value.ToString() == "Error")
{
row.Cells[5].Style.ForeColor = Color.DarkRed;
}
else if (row.Cells[5].Value.ToString() == "Processed and Complete")
{
row.Cells[5].Style.ForeColor = Color.Green;
}
else
{
row.Cells[5].Style.ForeColor = Color.Yellow;
}
}
}
else
{
ImageName = #"expand.png";
MasterDGVs.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = Image.FromFile(ImageName);
DetailDGVs.Visible = false;
}
}
else
{
DetailDGVs.Visible = false;
}
}
I have sort of working by adding:
MasterDGVs.MouseWheel += new MouseEventHandler(DetailDGV_Scroll);
DetailDGVs.MouseWheel += new MouseEventHandler(MasterDGV_Scroll);
and
private void DetailDGV_Scroll(object sender, MouseEventArgs e)
{
int scale = e.Delta * SystemInformation.MouseWheelScrollLines / 5;
DetailDGVs.Top = DetailDGVs.Top + scale;
}
private void MasterDGV_Scroll(object sender, MouseEventArgs e)
{
int scale = e.Delta * SystemInformation.MouseWheelScrollDelta / 5;
MasterDGVs.Top = MasterDGVs.Top - scale;
}

Add dynamic controls (PictureBox) with position data read from text file

I have text file with one line in it. The line looks like this:
100 300 200 400 658 487 2636 254 245 527
These numbers represent X and Y coordinates of points (first and second are X and Y of point N1, third and fourth are X and Y of point N2,...., ).
I read the file and put it in an array.
My next step is to draw the picture boxes in a container (panel).
The problem is that the panel is only showing the control with last coordinates.
private void CreateBlastHole(string[] pointCoordinate)
{
PictureBox blastHole = new PictureBox();
blastHole.Height = 15;
blastHole.Width = 15;
blastHole.BackColor = Color.Blue;
for (int i = 0; i < pointCoordinate.Length; i++)
{
blastHole.Left = int.Parse(pointCoordinate[i]);
i = i + 1;
blastHole.Top = int.Parse(pointCoordinate[i]);
drawingPanel.Controls.Add(blastHole);
}
blastHole.Click += new EventHandler(BlastHole_Click);
ToolTip tooltip1 = new ToolTip();
// Set up delays for the tooltip
tooltip1.AutoPopDelay = 5000;
tooltip1.InitialDelay = 1000;
tooltip1.ReshowDelay = 500;
// Force the tooltip text to be displayed whether or not the form is active.
tooltip1.ShowAlways = true;
// Set up the tooltip text for the controls
int axisX = blastHole.Location.X;
int axisY = blastHole.Location.Y;
string coordinates = "Точка N " + blastHole.Name + "X = " + axisX.ToString() + " Y = " + axisY.ToString();
tooltip1.SetToolTip(blastHole, coordinates);
}
private void BlastHole_Click(object sender, EventArgs e)
{
MessageBox.Show(MousePosition.X.ToString(), MousePosition.Y.ToString());
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void openButton_Click(object sender, EventArgs e)
{
openFileDialogPoints.ShowDialog();
string name = openFileDialogPoints.FileName;
File.ReadAllLines(name);
string[] points = File.ReadAllText(name).Split( );
CreateBlastHole(points);
}
private void drawingPanel_Paint(object sender, PaintEventArgs e)
{
}
private void buttonDrawHole_Click(object sender, EventArgs e)
{
}
You need to move your code inside the for-loop, to create more than one PictureBox. Currently, you are only creating one instance, reusing it for each blastHole.
Try something like this instead:
private void CreateBlastHole(string[] pointCoordinate)
{
for (int i = 0; i < pointCoordinate.Length; i++)
{
PictureBox blastHole = new PictureBox();
blastHole.Height = 15;
blastHole.Width = 15;
blastHole.BackColor = Color.Blue;
blastHole.Left = int.Parse(pointCoordinate[i]);
i = i + 1;
blastHole.Top = int.Parse(pointCoordinate[i]);
drawingPanel.Controls.Add(blastHole);
blastHole.Click += new EventHandler(BlastHole_Click);
ToolTip tooltip1 = new ToolTip();
// Set up delays for the tooltip
tooltip1.AutoPopDelay = 5000;
tooltip1.InitialDelay = 1000;
tooltip1.ReshowDelay = 500;
// Force the tooltip text to be displayed whether or not the form is active.
tooltip1.ShowAlways = true;
// Set up the tooltip text for the controls
int axisX = blastHole.Location.X;
int axisY = blastHole.Location.Y;
string coordinates = "Точка N " + blastHole.Name + "X = " + axisX.ToString() + " Y = " + axisY.ToString();
tooltip1.SetToolTip(blastHole, coordinates);
}
}

Categories