How to dynamically resize a label inside a WPF application? - wpf

I need to know how I could dynamically resize a label in a WPF application.
I've already found a sample in this article which has already achieved both dragging and resizing a label at the same time.
I dug into the code, and to make it short, I found out that inside OnMouseMove event of the label, it checks the mouse cursor shape and if it was Hand it will do the dragging and if it was either of the resizing arrows it will do the resizing correspondingly.
Check it out. you'll see.
In this certain example I couldn't manage to find out how the cursor shape changes to resizing arrows when the mouse is hovered on the label's border.
So
I either need to find out 'how I could change the mouse cursor shape to resizing arrows when hovered on a label's border', OR to find a new approach to resize a label, dynamically.

Changing the cursor is done via the this.Cursor property.
I opened the code in the article and saw how they do it...
In the OnMouseMove the cursor is changed if the left mouse button is NOT clicked:
Point currentLocation = e.MouseDevice.GetPosition(wnd);
......
......
const int dragHandleWidth = 3;
var bottomHandle = new Rect(0, height - dragHandleWidth, width, dragHandleWidth);
var rightHandle = new Rect(width - dragHandleWidth, 0, dragHandleWidth, height);
Point relativeLocation = wnd.TranslatePoint(currentLocation, this);
if (rightHandle.Contains(relativeLocation))
{
this.Cursor = Cursors.SizeWE;
}
else if (bottomHandle.Contains(relativeLocation))
{
this.Cursor = Cursors.SizeNS;
}
else
{
this.Cursor = Cursors.Hand;
}
In other words, they check if the current mouse location is within 3 px of the bottom or right border, if it is, they change the cursor accordingly...
You can easily change this logic to suite your needs....

Related

How to work around a Windows ListView issue?

If the listview (in Details mode) is scrolled down and then you resize the listview, and if you resize columns in the Resize event or even Layout event, the contents get corrupted badly.
To reproduce, make a new C# project and put this code in there:
private void Form1_Load(object sender, EventArgs e)
{
ListView lv = new ListView();
lv.Size = ClientSize;
lv.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
lv.Columns.Add(new ColumnHeader());
lv.Columns.Add(new ColumnHeader());
lv.View = View.Details;
lv.FullRowSelect = true;
lv.Resize += lv_Resize;
Controls.Add(lv);
string[] s = new string[2];
s[0] = "hrd";
s[1] = "igwegmg";
for (int i = 0; i < 20; i++)
{
lv.Items.Add(new ListViewItem(s));
}
lv_Resize(lv, null);
}
private void lv_Resize(object sender, EventArgs e)
{
ListView lv = (ListView)sender;
lv.Columns[1].Width = lv.ClientSize.Width - lv.Columns[0].Width;
}
Run it, scroll the list down a bit, resize the form to show all items by dragging the bottom of the form downwards.
Resize it smaller to where the scroll bar shows up, then it gets worse.
Or instead of resizing just maximize and restore the form.
Notice also there's a bunch (depending on how much you scrolled) of empty items at the top of the listview, you cant click on them. To restore it to normal you have to do one of two things.
Repopulate the items (not good - I have too many items and I lose my scroll position).
manually if you resize the form to where the scrollbar pops up, then you scroll the scroll bar to the bottom, then move your mouse off the scroll bar, and then back on top of the scrollbar you will see the scrollbar resize itself, at which point you can drag the scrollbar to the top, and then its back to normal.
If you RedrawItems, then at least you can see all the items again, but you still get the blank items at the top. Doing a begininvoke to a function that calls RedrawItems after a resize/layout event doesn't always work.
Any ideas on this bug? I really don't want to use any other controls or third party software.
Noticed other ListView's in my app not exhibiting the bug. Found out its because they were resizing columns inside the Form's Resize event.
Workaround: Dont Resize columns in the ListView.Resize() but do it in the Form.Resize() event.
I'll leave this open a littelwhile incase some of you already been researching for a workaround to use ListView.Resize()

Change cursor to image in WPF.

I am trying to implement a "stamping" feature. I am selecting an image from a list, and using it to stamp on the clicked position on my canvas.
I have read several solutions on how to change the cursor, but they involved simply changing the ico texture.
I want to be able to preview in real time what I will be stamping. So if I change the rotation of the stamp, the cursor needs to rotate appropriately, if I scale the stamp the cursor needs to be scaled, and if I switch the stamp the cursor needs to switch.
I tried adding an image to an observablecollection, and binding it to the canvas. Then I tried updating the position, image, scale inside the MouseMove event of the canvas, but it doesnt work.
Here is the MouseMove function:
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (currentTool == "staticBrush" && lvDataBinding.SelectedIndex != -1)
{
canvasImages[0].Name = srcImages[lvDataBinding.SelectedIndex].Name;
canvasImages[0].BmpImage = new BitmapImage(new Uri(canvasImages[0].Name, UriKind.Relative));
scale(canvasImages[0]);
canvasImages[0].OffsetX = e.GetPosition(canvasDataBinding).X;
canvasImages[0].OffsetY = e.GetPosition(canvasDataBinding).Y;
}
}
You have two main options... you can either follow a fairly complex tutorial such as WPF Tutorial - How To Use Custom Cursors on TechPro, which should enable you to create a Cursor from just about any WPF UIElement, or you can simply hide the Cursor by setting Cursor = Cursors.None and replacing it with your own Image... of course, with this method, you'd also be responsible for moving the Image wherever the mouse cursor moves.

How can I hide the cursor in transparent WPF window?

How can I hide the cursor in a WPF window that is fully transparent (alpha=0).
I tried the usual
this.Cursor = System.Windows.Input.Cursors.None;
and it works on areas with content where alpha > 0 but when the cursor moves to an area - in the same window - where the background is fully transparent the cursor re-appears.
I also added
System.Windows.Input.Mouse.OverrideCursor = System.Windows.Input.Cursors.None;
but that didn't help.
I realize that setting the alpha of background to 1 might be a solution but for various reasons this creates other problems...
Maybe as a work-around you can create a tiny non-transparent area somewhere, and move the mouse there just before hiding it:
// Coordinates of your non-transparent area:
var x = 10;
var y = 10;
System.Windows.Forms.Cursor.Position = new System.Drawing.Point(x, y);
this.Cursor = System.Windows.Input.Cursors.None;

How to hide the border around child window

I have a child Window , and I am displaying it from the code behind as below:
ChildPhotoViewer PhotoViewer = new ChildPhotoViewer();
PhotoViewer.DataContext = selectedPhoto;
PhotoViewer.Title = selectedPhoto.strTitle.ToString();
PhotoViewer.Show();
But While Displaying the child window I am getting the Close Button and a Border thickness arround the Window.
I am able to hide the Close Button but is there a way to hide the thickness(Border) across the child window.
Edit:
![alt text][1]
In the Image , there is border arround image after Collpasing the Close button and making
PhotoViewer.Title = null;
PhotoViewer.HasCloseButton = false;
I want to get rid of that Rectangular Border.
Have you tried:-
PhotoViewer.BorderThickness = new Thickness(0);
Edit
Perhaps you are refering to the title block across the top of the window?
PhotoViewer.Title = null;
PhotoViewer.HasCloseButton = false;
Edit
Third attempt.
The template for ChildWindow place the content in border with a 7 pixel margin. This also has an outer border which has a White background. That is what you are seeing in the image. The only way to eliminate it is to copy the ChildWindow template and edit it.
Depends on what you mean by the Border.
If you have a look at the Documentation you can see there is a border (with a thickness of 1) around the edge of the entire window that can be altered like Anthony mentions.
However there is also the window Chrome which in the default template has a number of borders. To change the thickness of these borders you will need to create a style without the borders being present.

Making a moveable control in WPF

I have a panel, within that panel are several rectangular controls (the number of controls vaires) I want the user to be able to move the controls around within the panel so that they can arrange the controls in the way that suits them best. does anyone have any resources i could read or simple tips which would get me headed down the right road?
thanks
I figured out a possible, simple method of moving a control in a drag/move style... Here are the steps.
Select an element in your control which you wish to be the movement area. This is the area in which, if me user holds the mouse down, the control will move. In my case it was a rectangular border at the top of the control.
Use the OnMouseDown event to set a boolean (in my case IsMoving) to true and the MouseUp event to set it to false
On the first MouseDown event, set some Point property (InitialPosition) using the following code
if (FirstClick)
{
GeneralTransform transform = this.TransformToAncestor(this.Parent as Visual);
Point StartPoint = transform.Transform(new Point(0, 0));
StartX = StartPoint.X;
StartY = StartPoint.Y;
FirstClick = false;
}
Now that you have the starting position, you need to get the position of the mouse relative to your movement control. This is so you dont end up clicking the middle of your header to move it and it instantly moves the top left of the control to the mouse pointer location. To do this, place this code in the MouseDown event:
Point RelativeMousePoint = Mouse.GetPosition(Header);
RelativeX = RelativeMousePoint.X;
RelativeY = RelativeMousePoint.Y;
Now you have the point the control originated at (startX and STartY), the position of the mouse within your movement control (RelativeX, RelativeY), we just need to move the control to a new location! There are a few steps involved in doing this. Firstly your control needs to have a RenderTransform which is a TranslateTransform. If you dont want to set this in XAML, feel free to set it using this.RenderTransform = new TranslateTransform.
Now we need to set the X and Y coordinates on the RenderTransform so that the control will move to a new location. The following code accomplishes this
private void Header_MouseMove(object sender, MouseEventArgs e)
{
if (IsMoving)
{
//Get the position of the mouse relative to the controls parent
Point MousePoint = Mouse.GetPosition(this.Parent as IInputElement );
//set the distance from the original position
this.DistanceFromStartX= MousePoint.X - StartX - RelativeX ;
this.DistanceFromStartY= MousePoint.Y - StartY - RelativeY;
//Set the X and Y coordinates of the RenderTransform to be the Distance from original position. This will move the control
TranslateTransform MoveTransform = base.RenderTransform as TranslateTransform;
MoveTransform.X = this.DistanceFromStartX;
MoveTransform.Y = this.DistanceFromStartY;
}
}
As you can guess, there is a bit of code left off(variable declarations etc) but this should be all you need to get you started :) happy coding.
EDIT:
One problem you may encounter is that this allows you to move the control out of the area of its parent control. Here is some quick and dirty code to fix that issue...
if ((MousePoint.X + this.Width - RelativeX > Parent.ActualWidth) ||
MousePoint.Y + this.Height - RelativeY > Parent.ActualHeight ||
MousePoint.X - RelativeX < 0 ||
MousePoint.Y - RelativeY < 0)
{
IsMoving = false;
return;
}
Place this code in your MouseMove event before the actual movement takes place. This will check if the control is trying to move outside the bounds of the parent control. The IsMoving = false command will cause the control to exit movement mode. This means that the user will need to click the movement area again to try to move the control as it will have stopped at the boundary. If you want the control to automatically continue movement, just take that line out and the control will jump back onto the cursor as soon as it is back in a legal area.
You can find a lot of inspiration here:
http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part1.aspx
http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part2.aspx
http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part3.aspx
http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part4.aspx

Resources