moving multiple controls - wpf

I need to move a multiple textboxes with a mouse cursor.
I decided that I do it that way.
If a textbox is clicked (and Control button is pressed) textbox is added to list of selected items. Then when button is still pressed and when mouse moves I do an operation of moving controls. However my code doesn't work well. Textboxes are moving but very very fast. Here is my code
List<TextBox> items;
private void txtBox_PreviewMouseDown(object sender, RoutedEventArgs e)
{
isClicked = true;
startPoint = Mouse.GetPosition( (sender as TextBox).Parent);
items = CurrentSelection;
}
private void txtBox_PreviewMouseMove(object sender, RoutedEventArgs e)
{
Point mousePos = Mouse.GetPosition(parentCanvas);
if (isClicked)
{
foreach (TextBox item in items)
{
double left = Canvas.GetLeft(item);
double top = Canvas.GetTop(item);
Canvas.SetLeft(item, left + (startPoint.X - mousePos.X));
Canvas.SetTop(item, top + (startPoint.Y - mousePos.Y));
}
}
}
Basically I iterate through all selected items and change their position on canvas. However I probably calculate a new position in a wrong way.

The problem is, that you always calculate the delta to the initial start point. You must actualize startPoint after every call to txtBox_PreviewMouseMove. Somethin like...
private void txtBox_PreviewMouseMove(object sender, RoutedEventArgs e) {
Point mousePos = Mouse.GetPosition(parentCanvas);
if (isClicked){
foreach (TextBox item in items) {
double left = Canvas.GetLeft(item);
double top = Canvas.GetTop(item);
Canvas.SetLeft(item, left + (startPoint.X - mousePos.X));
Canvas.SetTop(item, top + (startPoint.Y - mousePos.Y));
}
startPoint=mousePoint;
}
}
...should do the job. Another thing I have seen, is that the direction is probably inverted. This can be easily corrected. Change the calculcation to...
Canvas.SetLeft(item, left + (mousePos.X-startPoint.X ));
Canvas.SetTop(item, top + (mousePos.Y-startPoint.Y));
... and this problem should also be gone.

Related

Prevent WPF Image in border from panning too far

I have a WPF Image inside a Border I currently am able to click and drag to pan the image. I want to prevent users from dragging the image off the screen. Perhaps a minimum of 100 pixels should be showing at any border. That is, if a user drags the image all the way to the left, most of the image will disappear, but 100 pixels will still be hanging out toward the left boundary of the border.
Here's my current code for the MouseMove and LeftClick event:
private void img_Box_MouseMove(object sender, MouseEventArgs e)
{
if (!img_Box.IsMouseCaptured) return;
var tt = (TranslateTransform)((TransformGroup)img_Box.RenderTransform).Children.First(tr => tr is TranslateTransform);
Vector v = start - e.GetPosition(img_Border);
tt.X = origin.X - v.X;
tt.Y = origin.Y - v.Y;
}
private void img_Box_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
img_Box.CaptureMouse();
var tt = (TranslateTransform)((TransformGroup)img_Box.RenderTransform).Children.First(tr => tr is TranslateTransform);
start = e.GetPosition(img_Border);
origin = new System.Windows.Point(tt.X, tt.Y);
}
I think I should be able to put a pretty simple condition on that to achieve my desired result, but I can't figure out what the condition should be.

Using Shift key Multi selection of checkbox( Find Controls within 2 points/ rectangle

In order to select multiple checkbox within Wrap panel using Shift Key.
Capturing the Mouse down event position on Shift Keydown, on second mouse down with shift keydown, getting the 2 positions of the selection, then Need to Select the checkbox control with in the selected area.
How do I find the controls within 2 positions (System.Window.Point) or System.Windows.rect. The following code is selecting all of the checkbox within the wrappanel(lesscolorpanel).
private System.Windows.Point startPoint;
System.Windows.Point checkpPoint;
private System.Windows.Point PointWhereMouseIs;
private void LessColourPanel_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{
if (startPoint == checkpPoint)
{
//GET THE MOUSE POSITION
startPoint = Mouse.GetPosition(lessColourPanel);
PointWhereMouseIs = checkpPoint;
}
else if(PointWhereMouseIs==checkpPoint)
{
//CAPTURE END MOUSE POSITION
PointWhereMouseIs = Mouse.GetPosition(lessColourPanel);
//FIND CONTROLS WIHIN RECTANGLE
Rect selareaRect = new Rect(startPoint, PointWhereMouseIs);
foreach (System.Windows.Controls.CheckBox chkitemBox in FindVisualChildren<System.Windows.Controls.CheckBox>(lessColourPanel))
{
var rectBounds = VisualTreeHelper.GetDescendantBounds(chkitemBox);
Vector vector = VisualTreeHelper.GetOffset(chkitemBox);
rectBounds.Offset(vector);
if (rectBounds.IntersectsWith(selareaRect))
{
chkitemBox.IsChecked = true;
}
}
startPoint = checkpPoint;
}
}
}
Got it, and for viewers refer Ashley Davis post
The credit goes to Ashley Davis.

How to set row selection after releasing the mouse left click?

I have a datagridview. In this gridview when I left click and hold on the line and drag and drop it down to another line it is working fine but the selection of row remain same.
eg. If I select row# 2 and drag it to row# 4 , row# 2 drop at position 4 but row selection remain same. I want that when I drop it to row# 4 selected row should be row# 4.
I have done some code for drag and drop functionality.
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
// If the mouse moves outside the rectangle, start the drag.
if (dragBoxFromMouseDown != Rectangle.Empty &&
!dragBoxFromMouseDown.Contains(e.X, e.Y))
{
// Proceed with the drag and drop, passing in the list item.
DragDropEffects dropEffect = dataGridView1.DoDragDrop(
dataGridView1.Rows[rowIndexFromMouseDown],
DragDropEffects.Move);
}
}
}
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;
if (rowIndexFromMouseDown != -1)
{
Size dragSize = SystemInformation.DragSize;
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
e.Y - (dragSize.Height / 2)),
dragSize);
}
else
// Reset the rectangle if the mouse is not over an item in the ListBox.
dragBoxFromMouseDown = Rectangle.Empty;
}
private void dataGridView1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void dataGridView1_DragDrop(object sender, DragEventArgs e)
{
Point clientPoint = dataGridView1.PointToClient(new Point(e.X, e.Y));
// Get the row index of the item the mouse is below.
rowIndexOfItemUnderMouseToDrop =
dataGridView1.HitTest(clientPoint.X, clientPoint.Y).RowIndex;
// If the drag operation was a move then remove and insert the row.
if (e.Effect== DragDropEffects.Move)
{
DataGridViewRow rowToMove = e.Data.GetData(
typeof(DataGridViewRow)) as DataGridViewRow;
dataGridView1.Rows.RemoveAt(rowIndexFromMouseDown);
dataGridView1.Rows.Insert(rowIndexOfItemUnderMouseToDrop, rowToMove);
}
}
add the lines
dataGridView1.Rows[rowIndexOfItemUnderMouseToDrop].Selected = true;
dataGridView1.Rows[rowIndexFromMouseDown].Selected = false;
at the end of dataGridView1_DragDrop so that the selection will change. you have changed the rows problematically, and that means that the selection of the dataGridView did not changed with it.

Problem getting the actual width of control before rendering in wpf

I have a wpf window that hosts a control.
The window's height and width are set to SizeToControl.
Now I need to position this Window relative to the position of its parent window.(basically the Top right position).
(So my windows Top = ParentWindow.Top, and Left = ParentWindow.Left + ParentWindow.ActualWidth - control.ActualWidth so that my window is positioned inside the parent window but to its right corner)
So i will need to set the Top and Left of the window. To do this I need the Actual Width of the control that is being hosted inside it....but I can only get this once I actually do,
Window.Show(control,parent)
Is there a way to get around this problem? How do I get the actual rendered width of the control before it is actually shown?
Thanks!
Have you tried this approach?
public partial class ShellWindow : Window
{
public ShellWindow(IShellPresentationModel model)
{
InitializeComponent();
this.Loaded += ShellWindow_Loaded;
}
void ShellWindow_Loaded(object sender, RoutedEventArgs e)
{
var innerWindow = new InnerWindow();
innerWindow.Owner = this;
innerWindow.Loaded += InnerWindow_Loaded;
innerWindow.Show();
}
void InnerWindow_Loaded(object sender, RoutedEventArgs e)
{
var w = (InnerWindow)sender;
w.Owner = this;
w.Top = this.Top;
w.Left = this.Left + this.ActualWidth - w.ActualWidth;
}
}

Scroll with mousewheel and zoom image with panning

I would like to make a small silverlight app which displays one fairly large image which can be zoomed in by scrolling the mouse and then panned with the mouse.
it's similar to the function in google maps and i do not want to use deepzoom.
here is what i have at the moment. please keep in mind that this is my first silverlight app:
this app is just for me to see it's a good way to build in a website. so it's a demo app and therefor has bad variable names.
the initial image is 1800px width.
private void sc_MouseWheel(object sender, MouseWheelEventArgs e)
{
var st = (ScaleTransform)plaatje.RenderTransform;
double zoom = e.Delta > 0 ? .1 : -.1;
st.ScaleX += zoom;
st.ScaleY += zoom;
}
this works, but could use some smoothing and it's positioned top left and not centered.
the panning is like this:
found it # Pan & Zoom Image
and converted it to this below to work in silverlight
Point start;
Point origin;
bool captured = false;
private void plaatje_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
plaatje.CaptureMouse();
captured = true;
var tt = (TranslateTransform)((TransformGroup)plaatje.RenderTransform)
.Children.First(tr => tr is TranslateTransform);
start = e.GetPosition(canvasje);
origin = new Point(tt.X, tt.Y);
}
private void plaatje_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
plaatje.ReleaseMouseCapture();
captured = false;
}
private void plaatje_MouseMove(object sender, MouseEventArgs e)
{
if (!captured) return;
var tt = (TranslateTransform)((TransformGroup)plaatje.RenderTransform).Children.First(tr => tr is TranslateTransform);
double xVerschuiving = start.X - e.GetPosition(canvasje).X;
double yVerschuiving = start.Y - e.GetPosition(canvasje).Y;
tt.X = origin.X - xVerschuiving;
tt.Y = origin.Y - yVerschuiving;
}
so the scaling isn't smooth and the panning isn't working, because when i click it, the image disappears.
first thing I noticed was this:
var st = (ScaleTransform)plaatje.RenderTransform;
and
(TransformGroup)plaatje.RenderTransform
. So in one handler, you're casting "plaatje.RenderTransform" to ScaleTransform, in the other you're casting to TransformGroup?
This is probably causing an exception, making your image disappear.
For the zooming part, you might want to try setting the RenderTransformOrigin of the object you want to scale ("plaatje"?) to "0.5,0.5", meaning the center of the UI element. So the image will be scaled around its center point instead of its top left corner.
Cheers, Alex

Resources