How DragMove works? (Which properties it changes?) - c#

I am making a simple window in WPF (like Overwolf), in Overwolf there is a circle in the top-left of the screen and when you drag it, its moving back to the corner with simple Animation.
So I tried to make the same effect using DoubleAnimation on the LeftProperty but it only works once (The first time you drag its working, the second its just stay where you dragged it).
My XAML:
<Window x:Class="Overwoof.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Name="Main"
Width="200"
Height="200"
AllowsTransparency="True"
WindowStyle='None'
IsHitTestVisible="True"
Topmost="True"
Background="Transparent"
MouseLeftButtonUp="onDragLeave"
WindowStartupLocation="Manual">
<Grid IsHitTestVisible="True" Name="mainGrid" MinHeight="200" MinWidth="200">
<Ellipse MouseLeftButtonDown="DragStart" Name="logo" Width="100" Height="100" Fill="Red" Opacity="0.5" Margin="12,24,66,37" IsManipulationEnabled="True" />
</Grid>
My C# code:
private void DragStart(object sender, MouseEventArgs e)
{
Main.DragMove();
}
private void onDragLeave(object sender, MouseEventArgs e)
{
DoubleAnimation da = new DoubleAnimation();
da.From = Main.Left;
da.To = -20;
da.Duration = new Duration(TimeSpan.FromSeconds(0.2));
da.Completed += new EventHandler(AnimationCompleted);
Main.BeginAnimation(Window.LeftProperty, da);
}
Thx, BBLN.

change da.To = -20; toda.To -= 20;

Related

How to close current user Control and open new User control in WPF inside user control

I am new in WPF application i have to develop app with user control, User control will work like pages
I have open user control in MainWindow which will select language upon click and then close (current) language selection control and open another
MainWindow Code
<Window x:Class="WorkForceVisitor.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WorkForceVisitor"
mc:Ignorable="d"
Title="Work Force Pro Visitor" Icon="Images/favicon.ico" Height="800" Width="1200">
<Window.Background>
<ImageBrush ImageSource="Images/bg.png"/>
</Window.Background>
<Grid Margin="10,0,1,5" RenderTransformOrigin="0.556,0.496" Height="754" VerticalAlignment="Bottom">
<StackPanel Name="myStack" Grid.Row="1" >
</StackPanel>
</Grid>
</Window>
MainWindow.cs
private Header _Header;
private Visitor _Visitor;
private Control _currentUser;
public MainWindow()
{
InitializeComponent();
_Header = new Header();
_LanguageSelection = new LanguageSelection();
_Visitor = new Visitor();
_currentUser = _LanguageSelection;
myStack.Children.Add(_currentUser);
}
user will click either arabic or english
upon button click we will close LanguageSelection control
and open Visitor controll in StackPanel Name="myStack"
which is inside the mainWindow
LanguageSelection
<UserControl x:Class="WorkForceVisitor.LanguageSelection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WorkForceVisitor"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10,0,1,5" RenderTransformOrigin="0.556,0.496" Height="754" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*"/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image MouseDown="EnglishPress" Grid.Column="1" HorizontalAlignment="Right" Height="200" Margin="0,0,38,272" VerticalAlignment="Bottom" Width="290" Source="Images/english.PNG">
<Image.OpacityMask>
<ImageBrush ImageSource="Images/arabic.PNG"/>
</Image.OpacityMask>
</Image>
<Image MouseDown="AranbicPress" Grid.Column="2" Height="200" Margin="50,0,0,272" VerticalAlignment="Bottom" Source="Images/arabic.PNG" RenderTransformOrigin="0.511,0.527" HorizontalAlignment="Left" Width="285">
<Image.OpacityMask>
<ImageBrush ImageSource="Images/english.PNG"/>
</Image.OpacityMask>
</Image>
<Image Grid.Column="1" HorizontalAlignment="Right" Height="100" Margin="0,0,440,517" VerticalAlignment="Bottom" Width="294" Grid.ColumnSpan="2" Source="Images/Logo.png"/>
</Grid>
</UserControl>
languageselection.cs
static bool isEnglish = false;
private void AranbicPress(object sender, MouseButtonEventArgs e)
{
// need to close current control and show visitor control in mainWindow
}
private void EnglishPress(object sender, MouseButtonEventArgs e)
{
// need to close current control and show visitor control in mainWindow
isEnglish = true;
}
I am not a pro, but this should work:
MainWindow.cs
public static Window Current;
private Header _Header;
private Visitor _Visitor;
private Control _currentUser;
public MainWindow()
{
Current = this;
InitializeComponent();
_Header = new Header();
_LanguageSelection = new LanguageSelection();
_Visitor = new Visitor();
_currentUser = _LanguageSelection;
myStack.Children.Add(_currentUser);
}
languageselection.cs
static bool isEnglish = false;
private void AranbicPress(object sender, MouseButtonEventArgs e)
{
MainWindow.Current.myStack.Children.Clear();
MainWindow.Current.myStack.Children.Add(MainWindow.Current._Visitor);
}
private void EnglishPress(object sender, MouseButtonEventArgs e)
{
MainWindow.Current.myStack.Children.Clear();
MainWindow.Current.myStack.Children.Add(MainWindow.Current._Visitor);
isEnglish = true;
}
However:
1) I don't think you need stackpanel inside of the grid for just one child;
2) I don't think you need to initialize your usercontrols before user needs them;
3) I would probably better create methods in the MainWindow to replace the controls.

Polygon automatcally adjust to its above polygon

I'm making a Windows Desktop Application that have drag and drop functionality.
I'm using Polygon (And Images later) Shapes for drag and drop. The drag and drop functionality works fine but I want that if user drag any shape from the panel and when he drag other shape then the second shape automatically fix with first shape.
You'll understand it by take a look at below screenshots.
It is the Screen Shot of what happens when I drag Shapes
When user drop the polygon near the other polygon it will automatically adjust itself, if the same polygon drop in other area of canvas than a error will show to the user.
Here is my XAML Code
<Window x:Class="Images.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Images"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel
VerticalAlignment="Stretch"
Height="Auto">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
MinWidth="400"
Margin="10">
<GroupBox
DockPanel.Dock="Left"
Width="350"
Background="Aqua"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<WrapPanel Margin="0,10,0,0" VerticalAlignment="Top">
<Button Name="control" Content="Control" Height="30" Background="BlueViolet" Margin="5" Width="100"/>
<Button Name="motion" Content="Motion" Width="100" Margin="5" Background="Green" Height="30"/>
<Button Name="variable" Content="Variable" Width="100" Margin="5" Background="SeaGreen" Height="30"/>
<Button Name="sensor" Content="Sensor" Width="100" Margin="5" Background="OrangeRed" Height="30"/>
<Button Name="lcd" Content="LCD" Width="100" Margin="5" Height="30" Background="PaleVioletRed"/>
<Button Name="function" Content="Function" Width="100" Margin="5" Height="30" Background="Salmon"/>
<StackPanel Name="heaading" Width="350">
<TextBlock Name="controlName" TextAlignment="Center" Text="Controls"/>
</StackPanel>
<StackPanel Name="userControls" Orientation="Vertical">
<!-- Users Controls Items Goes Here -->
<Polygon Name="startProgram" Points="80,10, 80, 80, 135,80, 135, 45, 205, 45, 205, 80, 260, 80, 260,10" Fill="Chocolate" Stroke="Black" StrokeThickness="2" MouseLeftButtonDown="shape_MouseLeftButtonDown" />
<Polygon Name="endProgram" Fill="BlueViolet" Points="80,40, 80,80, 260,80, 260,40, 200,40, 200,10, 140,10,140,40" Stroke="Black" StrokeThickness="2" MouseLeftButtonDown="shape_MouseLeftButtonDown" />
</StackPanel>
</WrapPanel>
</GroupBox>
<!-- Change this to Canvas for work later -->
<Canvas x:Name="dropArea" DockPanel.Dock="Right" Margin="10" Background="#FF9760BF" Width="Auto" HorizontalAlignment="Stretch" AllowDrop="True" Drop="dropArea_Drop">
</Canvas>
</DockPanel>
</DockPanel>
</Window>
Here is my CS code
namespace Images
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void dropArea_Drop(object sender, DragEventArgs e)
{
var shape = e.Data.GetData(typeof(Polygon)) as Polygon;
Console.WriteLine("Polygon Name : " + shape.Name);
Polygon myPolygon = new Polygon();
myPolygon.Stroke = shape.Stroke;
myPolygon.Fill = shape.Fill;
myPolygon.StrokeThickness = 2;
Canvas.SetTop(myPolygon, e.GetPosition(dropArea).Y);
myPolygon.Points = shape.Points;
dropArea.Children.Add(myPolygon);
myPolygon.MouseRightButtonDown += new MouseButtonEventHandler(dragged_ShapeMouseDown);
}
private void dragged_ShapeMouseDown(object sender, MouseButtonEventArgs e)
{
//Show Options to Delete or set Value to current Polygon
}
private void shape_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Polygon shape = e.Source as Polygon;
DragDrop.DoDragDrop(shape, shape, DragDropEffects.Copy);
}
}
}
Problem
I'm using Canvas.setTop because without setting it my polygon show over the first.
Here I'm setting the polygon that fix with its above polygon but it can be left or right also as shown in below screenshot.
SOLUTION
For Deleting shape
myPolygon.MouseLeftButtonUp += new MouseButtonEventHandler(dragged_ShapeMouseDown);
private void dragged_ShapeMouseDown(object sender, MouseButtonEventArgs e)
{
if (dropArea.Children.Count > 0)
dropArea.Children.Remove(sender as Polygon);
}
Sacha Barber has got very nice article that describe exactly what you are trying to do i think...4 steps articles up to MVVM ! have a look these step1 and
step2, step3, step4 - I also used it in my own project ArchX
well, i think everything is there in my code : during onmove test the result and change the cursor. ondragend : use a HitHelper to determine where you release the mouse and return the shape his tested - then adjust the shape of the polygon regarding the hit result : below sample code - GuideLineManager
public Cursor HitTestGuide(Point p, RulerOrientation mode)
{
if (_Guides.Exists(g => (int)g.Info.Orientation == (int)mode && g.HitTest(p)))
{
return _Guides.First(g => (int)g.Info.Orientation == (int)mode && g.HitTest(p)).Cursor;
}
return Cursors.Arrow;
}
and the onDragEnd, call to get the hit tested object
public Guideline GetSnapGuide(Point hitPoint)
{
foreach (Guideline gl in Guides)
{
if (!gl.IsDisplayed) continue;
if (gl.Info.IsSnap && !gl.Info.IsMoving)
if (gl.IsOnGuide(hitPoint, _Container.dPicCapture))
{
return gl;
}
}
return null;
}

How can I force an image to overlay on the title bar of my WPF application?

I have a WPF application that has an animated .gif used to briefly direct user attention. The .gif sits just outside of the bounds of my app's window, such that it is underneath, and covered by, the title bar.
See below:
Is there a way to force it to overlay on top? It's defined in XAML like this:
<Grid>
<Image Margin="-5 -45 0 0" DockPanel.Dock="Left" gif:ImageBehavior.AnimatedSource="/Resources/jump.gif"
Width="30" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="45"/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>
And it looks alright at design-time:
I tried using DockPanel instead of Grid as its container to no avail.
Lastly, is it possible to have it behave as though it was collapsed? That is, have it not take up horizontal space between the ComboBox and the Legend Label
You need to use a Popup so that it gets its own window handle. This will also make it not take up space in the layout. As an added bonus (or maybe headache) you will be able to position it with its PlacementTarget and PlacementMode properties, since it looks like that is what you are trying to do anyway.
I used a Popup and it is working quite well, but with some very little flickering.
<Window x:Name="Window1" .../>
<Grid>
<Button Content="Show" HorizontalAlignment="Left" Margin="160,114,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
<Button Content="Hide" HorizontalAlignment="Left" Margin="265,114,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
<Popup x:Name="Popup1" UseLayoutRounding="True" IsOpen="False" Placement="Top" PlacementTarget="{Binding ElementName=Window1}">
<Image Source="C:\\Users\\Public\\Pictures\\Sample Pictures\\desert.jpg" Stretch="Fill" Width="75" Height="25"/>
</Popup>
</Grid>
</Window>
Code :
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Popup1.IsOpen = true;
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Popup1.IsOpen = false;
}
private void Window1_LocationChanged(object sender, EventArgs e)
{
double offset = Popup1.HorizontalOffset;
Popup1.HorizontalOffset = offset + 1;
Popup1.HorizontalOffset = offset;
}
Another approach (recommended) without Popup !
XAML
MainWindow.xaml
<Window x:Class="WpfWindow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="Window1" Title="MainWindow" Height="350" Width="525"
Closing="Window1_Closing" Activated="Window1_Activated" LocationChanged="Window1_LocationChanged">
<Grid x:Name="root"/>
</Window>
TitleBarWindow.xaml
<Window x:Class="WpfWindow.TitleBarWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Topmost="True"
Title="TitleBarWindow" AllowsTransparency="True" WindowStyle="None" Height="25" Width="200">
<Grid>
<Image Source="g:\\jellyfish.jpg" Stretch="Fill" HorizontalAlignment="Stretch"/>
</Grid>
</Window>
MainWindow.xaml.cs
namespace WpfWindow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
TitleBarWindow w = new TitleBarWindow();
public MainWindow()
{
InitializeComponent();
w.ShowActivated = true;
w.Background = Brushes.Red;
}
private void Window1_LocationChanged(object sender, EventArgs e)
{
Point pt = Window1.PointToScreen(new Point(0, 0));
w.Top = pt.Y - 27;
w.Left = pt.X;
}
private void Window1_Activated(object sender, EventArgs e)
{
Point pt = Window1.PointToScreen(new Point(0, 0));
w.Top = pt.Y-27;
w.Left = pt.X;
w.Show();
}
private void Window1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
w.Close();
}
}
}
Second approach is very good, works smoothly.

Move a rectangle on a canvas in WPF from code behind

In my XAML i have a listbox and some textboxes in a grid and a reactangle in a canvas:
Title="MainWindow" Height="350" Width="500" WindowStartupLocation="CenterScreen">
<Grid>
<ListBox HorizontalAlignment="Left"
Margin="12,12,0,12"
Name="listBoxContainer"
Width="120">
<ListBoxItem Content="Item1" />
<ListBoxItem Content="Item2" />
<ListBoxItem Content="Item3" />
</ListBox>
<TextBox Height="23"
Margin="138,12,85,0"
Name="textBoxAddress"
VerticalAlignment="Top" />
<TextBox Margin="138,41,85,12"
Name="textBoxMsg" />
<Button Content="Button"
Name="buttonAnimation"
Width="75"
Margin="0,10,5,0"
Height="23"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Click="Button1Click" />
<Canvas Name="CanvasAnimation">
<Rectangle Canvas.Left="408"
Canvas.Top="140"
Height="50"
Name="rectAnimation"
Stroke="Black"
Width="50" />
</Canvas>
</Grid>
From my code behind, i can move the rectangle from its position to a distance:
private void Button1Click(object sender, RoutedEventArgs e)
{
var trs = new TranslateTransform();
var anim3 = new DoubleAnimation(0, -200, TimeSpan.FromSeconds(2));
trs.BeginAnimation(TranslateTransform.XProperty, anim3);
trs.BeginAnimation(TranslateTransform.YProperty, anim3);
CanvasAnimation.RenderTransform = trs;
}
I would like to know how i can move the rectangle from its position to another position by coordinates? Like having the rectangle move to the position of the listbox or textbox
Please note that the below code assumes the coordinates for the button on the canvas and on the form are the same. This is not optimal, you should find a better solution, like putting the button on the canvas.
private void Button1Click(object sender, RoutedEventArgs e)
{
//Point relativePoint = buttonAnimation.TransformToAncestor(this).Transform(new Point(0, 0));
Point relativePoint = buttonAnimation.TransformToVisual(CanvasAnimation).Transform(new Point(0, 0));
var moveAnimX = new DoubleAnimation(Canvas.GetLeft(rectAnimation), relativePoint.X, new Duration(TimeSpan.FromSeconds(10)));
var moveAnimY = new DoubleAnimation(Canvas.GetTop(rectAnimation), relativePoint.Y, new Duration(TimeSpan.FromSeconds(10)));
rectAnimation.BeginAnimation(Canvas.LeftProperty, moveAnimX);
rectAnimation.BeginAnimation(Canvas.TopProperty, moveAnimY);
}
Sorry for the late answer, but it sounds like you want to set a dependency property.
rectAnimation.SetValue(Canvas.TopProperty, 0.0);
rectAnimation.SetValue(Canvas.LeftProperty, 0.0);
This will (instantly) place the rectangle at the top and left of the containing canvas.

Add Usercontrol To A Canvas

I have seen may examples one of them been
Add WPF control at runtime
Seem this solution has work for a lot of people. What the hell am I doing wrong? My Label won't Show on the canvas.
Label l = new Label();
l.Background = new LinearGradientBrush(Colors.Black, Colors.Black, 0);
canBackArea.Children.Add(l);
l.Visibility = System.Windows.Visibility.Visible;
l.Content = "Hello";
Canvas.SetLeft(l,20);
Canvas.SetTop(l, 20);
Canvas.SetZIndex(l, lableList.Count);
Canvas Has a white color, Thus the Background.
canBackArea is a Canvas
XML CODE
<ScrollViewer Grid.Row="2" HorizontalScrollBarVisibility="Visible">
<Canvas Name="canBackArea"
Width="500"
Height="300"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="White"
MouseMove="canBackArea_MouseMove">
<telerik:RadContextMenu.ContextMenu>
<telerik:RadContextMenu Name="mnuBack"
ItemClick="ContextMenu_ItemClick"
Opened="mnuBack_Opened">
<telerik:RadMenuItem Name="mBackground" Header="Set Background Image" />
<telerik:RadMenuItem Name="mSize" Header="Set Size" />
<telerik:RadMenuItem Name="mLable" Header="Add Text" />
<telerik:RadMenuItem Name="mChangeText" Header="Change Text" />
</telerik:RadContextMenu>
</telerik:RadContextMenu.ContextMenu>
<Image Name="imgBackground" />
</Canvas>
</ScrollViewer>
After Add a lot of labels.
This is my MainWindow.xaml
<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">
<Canvas x:Name="canBackArea">
</Canvas>
and this is my codebehind.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Label l = new Label();
canBackArea.Children.Add(l);
l.Visibility = System.Windows.Visibility.Visible;
l.Content = "Hello";
Canvas.SetLeft(l, 20);
Canvas.SetTop(l, 20);
}
This works perfectly fine.
http://i.imgur.com/JooqS.png
It could depend on the context your using it in?
I have tried to reproduce your issue and I suspect the possible issues should be that
No Foreground color is set to Label controls.
zIndex should be more than any other children controls I think as Canvas.SetZIndex(l, canBackArea.Children.Count);
Below is what I have tried and tested.
XAML Code
<Window x:Class="TestApplication.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" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="269*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Label Content="New Label Content" Height="30" />
<TextBox x:Name="txtLabelContent" Width="200" Height="30"></TextBox>
<Button Margin="10 0 0 0" Height="30" Width="70" Click="Button_Click">Add Label</Button>
</StackPanel>
<Canvas Grid.Row="1" x:Name="canBackArea" Background="White" Grid.RowSpan="2">
</Canvas>
</Grid>
</Window>
Window code-behind
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace TestApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Label l = new Label();
l.Background = new LinearGradientBrush(Colors.Black, Colors.Black, 0);
l.Foreground = new LinearGradientBrush(Colors.White, Colors.White, 0);
canBackArea.Children.Add(l);
l.Visibility = System.Windows.Visibility.Visible;
l.Content = txtLabelContent.Text;
Canvas.SetLeft(l, 20);
Canvas.SetTop(l, 20);
Canvas.SetZIndex(l, canBackArea.Children.Count);
}
}
}
using your xaml and this
private void mnuBack_ItemClick(object sender, Telerik.Windows.RadRoutedEventArgs e)
{
Label l = new Label();
canBackArea.Children.Add(l);
l.Visibility = System.Windows.Visibility.Visible;
l.Content = "Hello";
Canvas.SetLeft(l, 20);
Canvas.SetTop(l, 20);
Canvas.SetZIndex(l, lableList.Count);
lableList.Add(l);
}
I can add labels
The Problem was i was using styles and it is some how over writing my lable, i replaced it with textbox and every thing seems fine....

Categories