Silverlight InkPresenter containing a button - silverlight

I have an InkPresenter on which I add a button
<StackPanel x:Name="SignStackPanel">
<InkPresenter x:Name="SighCanvas" Background="White" Height="346">
<Button Canvas.Left="6" Canvas.Top="275" Content="Button"
Height="71" Name="Clear" Width="160" Background="#FF9D9D9D"
Click="Clear_Click" />
</InkPresenter >
</StackPanel>
My C# code is
private Point currentPoint;
private Point oldPoint;
void SighCanvas_MouseMove(object sender, MouseEventArgs e)
{
currentPoint = e.GetPosition(this.SighCanvas);
Line line = new Line() {
X1 = currentPoint.X,
Y1 = currentPoint.Y,
X2 = oldPoint.X,
Y2 = oldPoint.Y
};
line.Stroke = new SolidColorBrush(Colors.Purple);
line.StrokeThickness = 4;
this.SighCanvas.Children.Add(line);
oldPoint = currentPoint;
}
void SighCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
currentPoint = e.GetPosition(SighCanvas);
oldPoint = currentPoint;
}
I am trying to create a simple paint app. When I draw something on the InkPresenter and if I drag it over the button my strokes appear on the button.
How do I prevent the strokes from appearing over the button?

Related

Drag and Drop work when debugging in visual studio but not on installed App

I have WPF app and i added some mouse events to a canvas in a window to enable drag and drop. it works fine when running the app from visual studio in debugging mode but it does not work when i run the app without debugging. can anyone help!
XAML
<Canvas Name="canvas"
Width="{Binding DialogWidth, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Height="{Binding DialogHight, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Transparent"
PreviewMouseDown="Grid_MouseDown"
PreviewMouseMove="Grid_MouseMove"
PreviewMouseUp="Grid_MouseUp">
<Canvas.RenderTransform>
<TranslateTransform x:Name="tt" />
</Canvas.RenderTransform>
</Canvas>
Code behind
private Point _mStart;
private Vector _mStartOffset;
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
var window = Application.Current.MainWindow;
var canvas = (Canvas) sender;
var tt = canvas.RenderTransform as TranslateTransform ;
_mStart = e.GetPosition(window);
if (tt != null) _mStartOffset = new Vector(tt.X, tt.Y);
canvas.CaptureMouse();
}
private void Grid_MouseMove(object sender, MouseEventArgs e)
{
var canvas = (Canvas)sender;
var tt = canvas.RenderTransform as TranslateTransform;
if (tt == null) return;
var window = Application.Current.MainWindow;
if (!canvas.IsMouseCaptured) return;
var offset = Point.Subtract(e.GetPosition(window), _mStart);
// if (-_mStartOffset.X + canvas.ActualWidth < window?.ActualWidth)
tt.X = _mStartOffset.X + offset.X * -1;
// if (-_mStartOffset.Y + canvas.ActualHeight < window?.ActualHeight)
tt.Y = _mStartOffset.Y + offset.Y;
}
private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
{
var canvas = (Canvas)sender;
canvas.ReleaseMouseCapture();
}
I found the solution, the problem was that Application.Current.MainWindow returns 0 for position (but Twist of fate it works in the debug mode as i mentioned before),
and when i used (UIElement)Application.Current.Resources["MainWindow"] it worked like a charm :)

WPF - Moving a Canvas

I have trouble with moving a canvas in a Window.
<Canvas x:Name="Canvas1" Height="200" Grid.Column="1" Margin="10,15,92,54" Grid.Row="1" Background="#FFECECEC" Grid.RowSpan="2" MouseDown="Canvas_MouseDown" MouseUp="Canvas_MouseUp" MouseMove="Canvas_MouseMove" >
<TextBox Height="100" Width="100" Margin="50,50,327,65" Background="Red"/>
<TextBox Height="100" Width="100" Margin="10,15,327,65" Background="Blue" />
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
This is code behind:
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
Canvas1.CaptureMouse();
point = Mouse.GetPosition(Grid1);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (Canvas1.IsMouseCaptured)
{
translate.X = e.GetPosition(Grid1).X - point.X;
translate.Y = e.GetPosition(Grid1).Y - point.Y;
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
Canvas1.ReleaseMouseCapture();
}
First time, it seem woork fine.
But second time i try to click on my canvas, this move but from initial position.
How can i fix it?
When initializing point on mouse down, subtract the current translation:
private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
Canvas1.CaptureMouse();
point = Mouse.GetPosition(Grid1);
point.X -= translate.X;
point.Y -= translate.Y;
}
Alternatively, always only add the difference vector:
private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
{
Canvas1.CaptureMouse();
point = Mouse.GetPosition(Grid1);
}
private void Canvas1_MouseMove(object sender, MouseEventArgs e)
{
if (Canvas1.IsMouseCaptured)
{
var p = e.GetPosition(Grid1);
var diff = p - point;
point = p;
translate.X += diff.X;
translate.Y += diff.Y;
}
}
Also make sure the Grid doesn't position the Canvas, by setting the Canvas alignment to Top/Left:
<Canvas x:Name="Canvas1" HorizontalAlignment="Left" VerticalAlignment="Top" ...>
And probably don't set a Margin, but instead initialize the TranslateTransform appropriately.

moving any control in wpf

I am trying to move control in wpf using Canvas
This is the XAML
<Canvas Grid.Column="1" Grid.Row="0" x:Name="DropCanvas" AllowDrop="True" DragOver="DropCanvas_DragOver"
Drop="Canvas_Drop" DragEnter="Canvas_DragEnter" Background="#12000000" >
<TextBox Canvas.Left="162" Canvas.Top="188" Height="23" Name="textBox1" Width="120"
PreviewMouseMove="textBox1_PreviewMouseMove"
PreviewMouseLeftButtonDown="textBox1_PreviewMouseLeftButtonDown"
PreviewMouseUp="textBox1_PreviewMouseUp" />
</Canvas>
and this is the Code
Point p = new Point();
private void textBox1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Control control = sender as Control;
control.CaptureMouse();
p = e.GetPosition(control);
}
private void textBox1_PreviewMouseMove(object sender, MouseEventArgs e)
{
Control control = sender as Control;
Point x = e.GetPosition(control);
if (e.LeftButton == MouseButtonState.Pressed)
{
Canvas.SetLeft(control, Canvas.GetLeft(control) + (x.X - p.X));
Canvas.SetTop(control, Canvas.GetTop(control) + (x.Y - p.Y));
}
p = x;
}
private void textBox1_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Control control = sender as Control;
control.ReleaseMouseCapture();
activated = false;
}
The code is working, but when it moves, the control shakes.
What is the proplem
When you call GetPosition you should use DropCanvas as the parameter instead of the control. You're seeing vibrations because the TextBox keeps moving and you need something fixed.
Alternatively, you can use the MouseDragElementBehavior available in Expression Blend SDK to move objects in a container.
Also, this project can be useful to you: http://www.codeproject.com/Articles/24681/WPF-Diagram-Designer-Part-4
public void dragme(object sender, MouseButtonEventArgs e)
{
if (_Move.IsChecked == true)
db.Attach((DependencyObject)sender);
}
//// MouseDragElementBehavior db;
private void canvass_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (_Move.IsChecked == true && filmgrid.Visibility == Visibility.Visible)// == true)
{
filmgrid.PreviewMouseDown += new MouseButtonEventHandler(dragme);
}

Drag/Drop Button in same application throwing an exception

I have a Canvas that contains a button which I want to be able to drag and drop into another canvas. I want to copy the button to the other Canvas. Here is the code I am using:
The XAML:
<Window>
<Grid>
<Canvas
Height="300"
Width="500"
Background="Gray">
<Canvas
Name="cnvToolBox"
Canvas.Left="10"
Canvas.Top="10"
Background="AliceBlue"
Width="100"
Height="200">
<Button
Content="Drag Me!"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown"
PreviewMouseMove="Button_PreviewMouseMove"></Button>
</Canvas>
<Rectangle
Canvas.Left="119"
Canvas.Top="9"
Width="102"
Height="202"
StrokeDashArray="0.5 1.0 0.3"
Stroke="Black"
StrokeThickness="2"/>
<Canvas
Name="cnvButtonDropZone"
Canvas.Left="120"
Canvas.Top="10"
Width="100"
Height="200"
Background="LightGreen"
AllowDrop="True"
DragEnter="Canvas_DragEnter"
Drop="Canvas_Drop">
</Canvas>
</Canvas>
</Grid>
</Window>
Here's the Code Behind:
public partial class MainWindow : Window
{
private Point startPoint;
public MainWindow()
{
InitializeComponent();
}
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(null);
}
private void Button_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point currentPosition = e.GetPosition(null);
Vector diff = startPoint - currentPosition;
if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
Button button = sender as Button;
DataObject dragData = new DataObject("myFormat", button);
DragDrop.DoDragDrop(button, dragData, DragDropEffects.Copy);
}
}
private void Canvas_DragEnter(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent("myFormat") || sender == e.Source)
{
e.Effects = DragDropEffects.None;
}
}
private void Canvas_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent("myFormat"))
{
Button button = e.Data.GetData("myFormat") as Button;
Canvas canvas = sender as Canvas;
canvas.Children.Add(button);
}
}
}
When I drop the button I get the following exception when I'm adding the button to the canvas:
Specified element is already the logical child of another element. Disconnect it first.
I'm just trying to learn how to drag and drop controls and not really sure what that error means and how to resolve it. I don't know where I'm going wrong. Any suggestions would be welcome.
Thanks!
The button is owned by its parent cnvToolBox. You need to remove it from cnvToolBox before adding it to the canvas.
cnvToolBox.Children.Remove(button);
var canvas = sender as Canvas;
canvas.Children.Add(button);
This moves the button from your toolbox to the canvas. If you actually want to clone the item you want something like:
if (e.Data.GetDataPresent("myFormat"))
{
var contentControl = (ContentControl)e.Data.GetData("myFormat");
var constructorInfo = contentControl.GetType().GetConstructor(new Type[] {});
if (constructorInfo != null)
{
var newElement = (UIElement)constructorInfo.Invoke(new object[]{});
var newContentControl = newElement as ContentControl;
if(newContentControl != null)
{
newContentControl.Content = contentControl.Content;
}
((Panel)sender).Children.Add(newElement);
}
}
It's because the Button already has a parent associated with it; the previous Canvas.
You can set the parent of the Button to null; which will essentially remove it from the logical relationship.
button.Parent = null;
You will then be able to add that Button to another Canvas as you have done in your code behind.
You can also remove the Button from the Children property directly if you prefer and then add it accordingly within the new Canvas.
Canvas.Children.Remove(button);

Set events for new UIelements on runtime

I'm kinda confused with some problem, I'm doing a project where the user should be able to design questions with radio buttons, combo box, etc (kinda like toolbox from VS10 to design your XAML).
So far I can drag and drop an UIElement that I previously created, problem comes when the user creates a new element from my toolbox, I can't find the way to make that new UIElement to get the same events from my previosly created UIElement. Take a look at the code
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Canvas Height="190" HorizontalAlignment="Left" Margin="158,41,0,0" Name="canvas1" VerticalAlignment="Top" Width="322" AllowDrop="True">
<Button Content="PROBANDO" Height="23" Name="button" Width="75" Canvas.Left="113" Canvas.Top="43" PreviewMouseDown="button_PreviewMouseDown" PreviewMouseMove="button_PreviewMouseMove" MouseUp="button_MouseUp" IsEnabled="True" />
<TextBlock Canvas.Left="99" Canvas.Top="147" Height="23" Name="textBlock" Text="" Width="107" />
</Canvas>
<ListBox Height="190" Name="listBox" Width="126" Margin="12,41,365,80" >
<ListBoxItem Content="Radio Button" Selected="radio_Selected" Name="radio" />
<ListBoxItem Content="Text" Selected="text_Selected" Name="text" />
<ListBoxItem Content="Combo Box" Name="combo" Selected="combo_Selected" />
</ListBox>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Point p;
private void button_MouseUp(object sender, MouseButtonEventArgs e)
{
button.ReleaseMouseCapture();
}
private void button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
button.CaptureMouse();
p = e.GetPosition(canvas1);
}
private void button_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point x = e.GetPosition(canvas1);
if (e.LeftButton == MouseButtonState.Pressed)
{
Canvas.SetLeft(button, Canvas.GetLeft(button) + (x.X - p.X));
Canvas.SetTop(button, Canvas.GetTop(button) + (x.Y - p.Y));
}
p = x;
}
private void generic_PreviewMouseDown(UIElement sender, MouseEventArgs e)
{
Point x = e.GetPosition(canvas1);
if (e.LeftButton == MouseButtonState.Pressed)
{
Canvas.SetLeft(sender, Canvas.GetLeft(sender) + (x.X - p.X));
Canvas.SetTop(sender, Canvas.GetTop(sender) + (x.Y - p.Y));
}
p = x;
}
private void radio_Selected(object sender, RoutedEventArgs e)
{
RadioButton newRadio = new RadioButton();
canvas1.Children.Add(newRadio);
newRadio.PreviewMouseDown += generic_PreviewMouseDown(newRadio,?????);
textBlock.Text = listBox.SelectedIndex.ToString();
}
private void text_Selected(object sender, RoutedEventArgs e)
{
TextBox newText = new TextBox();
canvas1.Children.Add(newText);
textBlock.Text = (String)listBox.SelectedIndex.ToString();
}
private void combo_Selected(object sender, RoutedEventArgs e)
{
Console.Write("Combo");
textBlock.Text = (String)listBox.SelectedIndex.ToString();
}
}
Thanks!
If all you want to do is handle the mouse down on the new RadioButton, change this line:
newRadio.PreviewMouseDown += generic_PreviewMouseDown(newRadio,?????);
To this:
newRadio.PreviewMouseDown += generic_PreviewMouseDown;
Edit
And then you need to change the generic_PreviewMouseDown to the following:
private void generic_PreviewMouseDown(object sender, MouseEventArgs e)
{
UIElement elem = sender as UIElement;
Point x = e.GetPosition(canvas1);
if (e.LeftButton == MouseButtonState.Pressed)
{
Canvas.SetLeft(elem, Canvas.GetLeft(elem) + (x.X - p.X));
Canvas.SetTop(elem, Canvas.GetTop(elem) + (x.Y - p.Y));
}
p = x;
}

Resources