I've got this function that just draws an ellipse and places it on the given grid
public void drawEllipse(double top, double left, double height, double width, Grid grid)
{
Ellipse ellipse = new Ellipse();
ellipse.Height = height;
ellipse.Width = width;
SolidColorBrush brush = new SolidColorBrush();
brush.Color = Colors.Black;
ellipse.Stroke = brush;
ellipse.Fill = brush;
Canvas.SetTop(ellipse, top);
Canvas.SetLeft(ellipse, left);
grid.Children.Add(ellipse);
}
However, for some reason, it only wants to place the ellipse in the center of the grid, or (given fourth quadrant arguments) the fourth quadrant of the grid.
Am I doing something wrong?
You are adding your ellipse to a Grid control, but you're setting the Canvas.Top and Canvas.Left properties. Without the ellipse actually being on a Canvas, those two properties don't do anything. Either add a Canvas and use Canvas.Children.Add instead of Grid.Children.Add, or change your Canvas.SetTop and Canvas.SetLeft calls with calls to Grid.SetRow and Grid.SetColumn.
Related
I post this before and it was remove for being a duplicate. It is not. My problem is different then what that other people is doing. He is not doing zoom nor pan, and does not have a boarder.
I am using Stretch="Fill" to place my entire picture in the borders of an Image box. I am using a Border so that I can do Zoom and Pan. I am using the Canvas to draw rectangles around giving click areas. I want to map the left mouse click coordinates of the Canvas with zoom and pan back to the original image. here is my XAML code :
`
<Border x:Name="VideoPlayerBorder" ClipToBounds="True" Background="Gray" >
<Canvas x:Name="CanvasGridScreen" MouseLeftButtonDown="VideoPlayerSource_OnMouseLeftButtonDown" >
<Image x:Name="VideoPlayerSource" Opacity="1" RenderTransformOrigin="0.5,0.5" MouseLeftButtonUp="VideoPlayerSource_OnMouseLeftButtonUp" MouseWheel="VideoPlayerSource_OnMouseWheel" MouseMove="VideoPlayerSource_OnMouseMove" Width="{Binding Path=ActualWidth, ElementName=CanvasGridScreen}" Height="{Binding Path=ActualHeight, ElementName=CanvasGridScreen}" Stretch="Fill" >
</Image>
</Canvas>
`
here is my C# code:
`private void VideoPlayerSource_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
VideoPlayerSource.CaptureMouse();
var tt = (TranslateTransform)((TransformGroup)VideoPlayerSource.RenderTransform).Children.First(tr => tr is TranslateTransform);
start = e.GetPosition(VideoPlayerBorder);
origin = new Point(tt.X, tt.Y);
_stIR = start;
_stIR2 = start;
addRemoveItems(sender, e);
}
private void addRemoveItems(object sender, MouseButtonEventArgs e)
{
// this is the event that will check if we clicked on a rectangle or if we clicked on the canvas
// if we clicked on a rectangle then it will do the following
if (e.OriginalSource is Rectangle)
{
// if the click source is a rectangle then we will create a new rectangle
// and link it to the rectangle that sent the click event
Rectangle activeRec = (Rectangle)e.OriginalSource; // create the link between the sender rectangle
CanvasGridScreen.Children.Remove(activeRec); // find the rectangle and remove it from the canvas
}
// if we clicked on the canvas then we do the following
else
{
// generate a random colour and save it inside the custom brush variable
Custombrush = new SolidColorBrush(Color.FromRgb((byte)r.Next(1, 255),
(byte)r.Next(1, 255), (byte)r.Next(1, 233)));
// create a re rectangle and give it the following properties
// height and width 50 pixels
// border thickness 3 pixels, fill colour set to the custom brush created above
// border colour set to black
Rectangle newRec = new Rectangle
{
Width = 50,
Height = 50,
StrokeThickness = 3,
Fill = Custombrush,
Stroke = Brushes.Black
};
// once the rectangle is set we need to give a X and Y position for the new object
// we will calculate the mouse click location and add it there
Canvas.SetLeft(newRec, Mouse.GetPosition(CanvasGridScreen).X); // set the left position of rectangle to mouse X
Canvas.SetTop(newRec, Mouse.GetPosition(CanvasGridScreen).Y); // set the top position of rectangle to mouse Y
CanvasGridScreen.Children.Add(newRec); // add the new rectangle to the canvas
}
}
private void VideoPlayerSource_OnMouseWheel(object sender, MouseWheelEventArgs e)
{
TransformGroup transformGroup = (TransformGroup)VideoPlayerSource.RenderTransform;
ScaleTransform transform = (ScaleTransform)transformGroup.Children[0];
double zoom = e.Delta > 0 ? .2 : -.2;
double transformScaleX = Math.Round((transform.ScaleX + zoom), 2);
double transformScaleY = Math.Round((transform.ScaleY + zoom), 2);
if (transformScaleX <= 8.2 && transformScaleX >= 1)
{
transform.ScaleX = Math.Round(transform.ScaleX + zoom, 2);
transform.ScaleY = Math.Round(transform.ScaleY + zoom, 2);
zoomFactor2 = zoomFactor2 + zoom;
zoomFactor = zoomFactor2;
}
}
void PanMethod(MouseEventArgs e)
{
var tt = (TranslateTransform)((TransformGroup)VideoPlayerSource.RenderTransform).Children.First(tr => tr is TranslateTransform);
Vector v = start - e.GetPosition(VideoPlayerBorder);
if (zoomFactor > 1.0)
{
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
}
is there a function that would give me this information ? is there a way of using TransformGroup or ScaleTransform to return the actual location in the picture that was clicked? again the Image with possible zoom and/or pan
Check out: https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.visual.transformtovisual
The right way to translate coordinates back to the original pre-transforms control is to use the TransformToVisual helper. It's probably a good idea to do that regardless since transforms could be applied higher up in the stack.
In your case you want to call:
GeneralTransform transform = CanvasGridScreen.TransformToVisual(VideoPlayerSource);
Point normalizedPoint = transform.Transform(new Point(0, 0));
I'm trying to create a custom Shape, I started by creating a Rectangle.
Here's my code:
public class CustomRectangle : Shape
{
protected override Geometry DefiningGeometry
{
get
{
return new RectangleGeometry(new Rect(new Point(10, 10), new Size(100, 50)));
}
}
}
When I use 100 and 50 for the Width and Height of the Rectangle respectively, the Rectangle is being drawn perfectly.
However, if I increase either the Width and/or the Height for let's say 200 and 100, the drawn shape is not a Rectangle but a shape containing only two lines (looks like it it draw a Rectangle only it is cut - as if I have some boundaries int which the shape can be drawn).
I'm drawing the Shape on a Canvas, and here's the code for that:
private void MouseClick(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
if (mouseButtonEventArgs.LeftButton != MouseButtonState.Pressed)
{
m_downClick = new Point(-1, -1);
return;
}
m_downClick = mouseButtonEventArgs.GetPosition(sender as Canvas);
var newRect = new CustomRectangle {Width = 200, Height = 100, Stroke = Brushes.Black, Location = m_downClick};
Canvas.SetTop(newRect , m_downClick.Y);
Canvas.SetLeft(newRect , m_downClick.X);
(sender as Canvas).Children.Add(newRect);
}
What can be the reason for that?
The DefiningGeometry uses a hard coded location and size for the shape's geometry so the sizes passed in the MouseClick are ignored by the Shape when getting its geometry.
Use the Width and Height (dependency)properties of the shape in the DefiningGeometry to size the geometry to the intended size.
Is it possible to align the image icon from on a TabControl's ImageList to the right of the text?
Right now, the image icon gets put on the left, and the text is to the right of that. I would prefer the text to be on the left, and the icon to the right of that. Is this possible?
You can not do that unless you Draw the TabPage yourself. To do that you need to set the DrawMode property of the TabControl to OwnerDrawFixed and then handle the DrawItem Event.
This is a very simple example to do that, you can add some code to change the background color of the selected tab if you wish, to know which tab is selected just check the e.State value:
private void tabControl1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e)
{
// values
TabControl tabCtrl = (TabControl)sender;
Brush fontBrush = Brushes.Black;
string title = tabCtrl.TabPages[e.Index].Text;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
sf.LineAlignment = StringAlignment.Center;
int indent = 3;
Rectangle rect = new Rectangle(e.Bounds.X, e.Bounds.Y + indent, e.Bounds.Width, e.Bounds.Height - indent);
// draw title
e.Graphics.DrawString(title, tabCtrl.Font, fontBrush, rect, sf);
// draw image if available
if (tabCtrl.TabPages[e.Index].ImageIndex >= 0)
{
Image img = tabCtrl.ImageList.Images[tabCtrl.TabPages[e.Index].ImageIndex];
float _x = (rect.X + rect.Width) - img.Width - indent;
float _y = ((rect.Height - img.Height) / 2.0f) + rect.Y;
e.Graphics.DrawImage(img, _x, _y);
}
}
I have a a PictureBox on my Windows Forms.
I am drawing a Rectangle on the PictureBox, with ControlPaint.DrawReversibleFrame(), and want to code some boundaries, so I am only drawing on the PictureBox and not the whole screen.
How do I find the screen-coordinates of the topleft point of the PictureBox?
EDIT with solution: Here's my solution, if anybody need to code some PictureBox boundaries.
if (_isDragging) // If the mouse is being dragged, undraw and redraw the rectangle as the mouse moves.
{
pictureBoxMap.Refresh();
ControlPaint.DrawReversibleFrame(_theRectangleScreenCoords, BackColor, FrameStyle.Dashed); // Hide the previous rectangle by calling the DrawReversibleFrame method with the same parameters.
Point endPoint = ((Control)sender).PointToScreen(new Point(e.X, e.Y));
var topLeftPictureBoxMap = pictureBoxMap.PointToScreen(new Point(0, 0));
int width = endPoint.X - _startPointTheRectangleScreenCoords.X;
int height = endPoint.Y - _startPointTheRectangleScreenCoords.Y;
// limit rectangle in x-axis
var diff_x = pictureBoxMap.Width - (_startPointTheRectangleScreenCoords.X - topLeftPictureBoxMap.X);
var diff_x_2 = (pictureBoxMap.Width - (_startPointTheRectangleScreenCoords.X - topLeftPictureBoxMap.X)) - pictureBoxMap.Width;
if (width > diff_x)
{
width = diff_x;
}
else if(width < diff_x_2)
{
width = diff_x_2;
}
// limit rectangle i y-aksen
var diff_Y = pictureBoxMap.Height - (_startPointTheRectangleScreenCoords.Y - topLeftPictureBoxMap.Y);
var diff_Y_2 = (pictureBoxMap.Height - (_startPointTheRectangleScreenCoords.Y - topLeftPictureBoxMap.Y)) - pictureBoxMap.Height;
if (height > diff_Y)
{
height = diff_Y;
}
else if(height < diff_Y_2)
{
height = diff_Y_2;
}
_theRectangleScreenCoords = new Rectangle(
_startPointTheRectangleScreenCoords.X,
_startPointTheRectangleScreenCoords.Y,
width,
height);
ControlPaint.DrawReversibleFrame(_theRectangleScreenCoords, Color.Red, FrameStyle.Dashed); // Draw the new rectangle by calling DrawReversibleFrame again.
}
Use Control.PointToScreen( new Point(0, 0) ) where Control is your PictureBox.
See http://msdn.microsoft.com/en-us/library/system.windows.forms.control.pointtoscreen.aspx
I have a WinForm without a border (borderless). How can I add a 1px black border to the form?
public MainForm()
{
InitializeComponent();
this.DoubleBuffered = true;
Region = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, Width - 5, Height - 5, 10, 10)); // adjust these parameters to get the lookyou want.
}
[DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")]
private static extern IntPtr CreateRoundRectRgn
(
int nLeftRect, // x-coordinate of upper-left corner
int nTopRect, // y-coordinate of upper-left corner
int nRightRect, // x-coordinate of lower-right corner
int nBottomRect, // y-coordinate of lower-right corner
int nWidthEllipse, // height of ellipse
int nHeightEllipse // width of ellipse
);
I need a borderless form but I want to add a 1px border.
In the Paint event handler of the form, add this code:
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawRectangle(Pens.Black, new Rectangle(0, 0, Width - 1, Height - 1));
}
Good luck!
You could add a fully docked Panel, and another fully docked Panel as a child control. Set the padding of the outer Panel to 1 and the background color of the outer Panel to black.
Then set the background color of the inner Panel to SystemColors.Control.
If you don't want to paint,
Add 4 panels width or height 2 or 4 and black background colour
after dock them in 4 sides differently on top, right, bottom, left respectively
this.FormBorderStyle = FormBorderStyle.None;
Panel pnlTop = new Panel() { Height = 4, Dock = DockStyle.Top, BackColor = Color.Green };
this.Controls.Add(pnlTop);
Panel pnlRight = new Panel() { Width = 4, Dock = DockStyle.Right, BackColor = Color.Green };
this.Controls.Add(pnlRight);
Panel pnlBottom = new Panel() { Height = 4, Dock = DockStyle.Bottom, BackColor = Color.Green };
this.Controls.Add(pnlBottom);
Panel pnlLeft = new Panel() { Width = 4, Dock = DockStyle.Left, BackColor = Color.Green };
this.Controls.Add(pnlLeft);
You can also change their mouse pointer to resize icons also you can resize the form writing some code on mouse events.