How to disable "kinetic energy" of the UI object (UWP) - c#

I have Image on View that I can drag. But when I release the object it is moving for some time. How I can disable this?
My Xaml code:
<Image Grid.Column="0"
x:Name="CollageImg1"
Margin="370,469,1665,800"
Source="{Binding CollageImg1}"
RenderTransformOrigin="0.5,0.5"
ManipulationDelta="CollageImgage1_Manipulation"
Visibility="Visible">
<Image.RenderTransform>
<CompositeTransform />
</Image.RenderTransform>
</Image>
Method that uses for moving:
private void Manipulation(ManipulationDeltaRoutedEventArgs e, Image image)
{
CompositeTransform ct = (CompositeTransform)image.RenderTransform;
ct.TranslateX += e.Delta.Translation.X;// X move
ct.TranslateY += e.Delta.Translation.Y;// Ymove
}

Remove TranslateInertia from the ManipulationMode property of the Image.
E.g. set only TranslateX and TranslateY:
<Image ManipulationMode="TranslateX,TranslateY" ... />

Related

WPF Mousemove is a noticeable lag

I am making a UserControl called VolumeScrollBar to control the volume a video player I am working on. Now the problem I am having is when I slide my SwitchPath it moves noticeable slower than my mouse. How can I fix this ?
note: everything is working but the speed.
Also, I am not using the built in sliding bar because I do not like how it looks. So I designed my own Volume scroll bar in Adobe Illustrator.
here is my XAML code:
<Canvas x:Name="VolumeScrollBarCanvas" Height="21" Width="160" >
<Path x:Name="Path_7" Width="15" Height="13" Canvas.Left="0.777" Canvas.Top="3.556" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 67.6183,648C 67.5503,648 67.4809,648.019 67.4156,648.061L 62.6556,651.173L 61.3916,652L 55.9996,652C 54.5276,652 53.3329,653.193 53.3329,654.667C 53.3329,656.14 54.5276,657.333 55.9996,657.333L 61.3916,657.333L 62.6556,658.16L 67.4156,661.272C 67.4809,661.315 67.5503,661.333 67.6183,661.333C 67.8169,661.333 67.9996,661.169 67.9996,660.937L 67.9996,654.667L 67.9996,648.395C 67.9996,648.164 67.8169,648 67.6183,648 Z M 66.6663,650.144L 66.6663,654.667L 66.6663,659.189L 63.3863,657.044L 62.1209,656.217L 61.7889,656L 61.3916,656L 55.9996,656C 55.2649,656 54.6663,655.401 54.6663,654.667C 54.6663,653.932 55.2649,653.333 55.9996,653.333L 61.3916,653.333L 61.7889,653.333L 62.1209,653.116L 63.3849,652.289L 66.6663,650.144 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="WhiteBarPath" Width="81" Height="7" Canvas.Left="46.111" Canvas.Top="6.223" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 176.667,657.333L 102,657.333C 100.167,657.333 98.6667,655.833 98.6667,654L 98.6667,654C 98.6667,652.167 100.167,650.667 102,650.667L 176.667,650.667C 178.5,650.667 180,652.167 180,654L 180,654C 180,655.833 178.5,657.333 176.667,657.333 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="Path_8" Width="13" Height="20" Canvas.Left="24.151" Canvas.Top="0.639" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 78.6667,645.333C 77.9893,645.333 77.3347,645.451 76.7067,645.648C 81.5307,646.025 85.3333,650.212 85.3333,655.333C 85.3333,660.455 81.5293,664.641 76.7067,665.019C 77.3347,665.216 77.9893,665.333 78.6667,665.333C 83.0853,665.333 89.3333,660.856 89.3333,655.333C 89.3333,649.811 83.0853,645.333 78.6667,645.333 Z " HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Path x:Name="Path_9" Width="9.26" Height="15" Canvas.Left="19.168" Canvas.Top="3.556" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 73.1609,648C 72.6636,648 72.1849,648.085 71.7236,648.231C 75.2609,648.508 78.0503,651.579 78.0503,655.333C 78.0503,659.088 75.2609,662.159 71.7236,662.436C 72.1849,662.581 72.6636,662.667 73.1609,662.667C 76.4009,662.667 80.9836,659.384 80.9836,655.333C 80.9836,651.283 76.4009,648 73.1609,648 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="Path_10" Width="4" Height="5" Canvas.Left="18.11" Canvas.Top="8.266" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 72.4039,652.71C 72.2399,652.71 70.9452,652.756 70.6665,652.81L 70.6665,657.311C 71.0052,657.364 72.3412,657.306 72.4039,657.306C 73.6732,657.306 74.7012,656.276 74.7012,655.007C 74.7012,653.739 73.6732,652.71 72.4039,652.71 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="ColorBarPath" Width="81" Height="7" Canvas.Left="46.111" Canvas.Top="6.223" Stretch="Fill" Fill="#FF6557FF" Data="F1 M 176.667,657.333L 102,657.333C 100.167,657.333 98.6667,655.833 98.6667,654L 98.6667,654C 98.6667,652.167 100.167,650.667 102,650.667L 176.667,650.667C 178.5,650.667 180,652.167 180,654L 180,654C 180,655.833 178.5,657.333 176.667,657.333 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Ellipse x:Name="SwitchPath" MouseDown="SwitchPath_MouseDown" MouseMove="SwitchPath_MouseMove" Mouse.MouseUp="SwitchPath_MouseUp" Width="19" Height="19" Canvas.Left="115.444" Canvas.Top="0.889" Stretch="Fill" Fill="#FFFFFFFF" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="Path_7_Copy" Width="15" Height="13" Canvas.Left="0.777" Canvas.Top="3.556" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 67.6183,648C 67.5503,648 67.4809,648.019 67.4156,648.061L 62.6556,651.173L 61.3916,652L 55.9996,652C 54.5276,652 53.3329,653.193 53.3329,654.667C 53.3329,656.14 54.5276,657.333 55.9996,657.333L 61.3916,657.333L 62.6556,658.16L 67.4156,661.272C 67.4809,661.315 67.5503,661.333 67.6183,661.333C 67.8169,661.333 67.9996,661.169 67.9996,660.937L 67.9996,654.667L 67.9996,648.395C 67.9996,648.164 67.8169,648 67.6183,648 Z M 66.6663,650.144L 66.6663,654.667L 66.6663,659.189L 63.3863,657.044L 62.1209,656.217L 61.7889,656L 61.3916,656L 55.9996,656C 55.2649,656 54.6663,655.401 54.6663,654.667C 54.6663,653.932 55.2649,653.333 55.9996,653.333L 61.3916,653.333L 61.7889,653.333L 62.1209,653.116L 63.3849,652.289L 66.6663,650.144 Z " HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Path x:Name="Path_6" Width="13" Height="12" Stretch="Fill" Fill="#FFFFFFFF" Data="F1 M 61.5899,656.667L 56.0005,656.667C 54.8965,656.667 54.0005,655.769 54.0005,654.667C 54.0005,653.564 54.8965,652.667 56.0005,652.667L 61.5899,652.667L 67.3339,648.912L 67.3339,660.421L 61.5899,656.667 Z " HorizontalAlignment="Left" VerticalAlignment="Top" Canvas.Left="1.777" Canvas.Top="4.056"/>
<TextBlock x:Name="Displaytxb" Height="18" Canvas.Left="136.069" TextWrapping="Wrap" Text="100" Canvas.Top="1.917" Width="23" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="White"/>
</Canvas>
and here is my code behind:
private void ChangeTheVolume(double newVolume)
{
if (newVolume < 0 || newVolume > 100) return;
newVolume = Math.Round(newVolume);
double tempVolume = (ValumeMaxHigh * newVolume);
ColorBarPath.Width = tempVolume;
double pointX = (LocationMaxHigh * newVolume) + 46.11;
Canvas.SetLeft(SwitchPath, pointX); // set the left position of rectangle to mouse X
Displaytxb.Text = Convert.ToString(newVolume);
VolumeOut = Volume;
}
private void SwitchPath_MouseDown(object sender, MouseButtonEventArgs e)
{
Cursor = Cursors.Hand;
_handToolMove = true;
SwitchPath.CaptureMouse();
_startPoint = e.GetPosition(VolumeScrollBarCanvas);
double mouseCurrentLocation = Canvas.GetLeft(SwitchPath);
_mouseDownForHandToolOffSetX = _startPoint.X - mouseCurrentLocation;
}
private void SwitchPath_MouseMove(object sender, MouseEventArgs e)
{
if (_handToolMove)
{
Point v = e.GetPosition(VolumeScrollBarCanvas);
Volume = 0.6933 * v.X + 1.24946035807;
}
}
private void SwitchPath_MouseUp(object sender, MouseButtonEventArgs e)
{
if (_handToolMove)
{
Point v = e.GetPosition(VolumeScrollBarCanvas);
Volume = 0.6933 * v.X + 1.25;
SwitchPath.ReleaseMouseCapture();
_handToolMove = false;
Cursor = Cursors.Hand;
}
}
}
public VolumeScrollBar()
{
RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
InitializeComponent();
}
The issue here isn't the speed of the render but just in your geometry calculations. The volume is not scaling 1:1 with the mouse movement. (That is, in terms of y=mx+b, m needs to be 1).
So, this line in SwitchPath_MouseMove -
Volume = 0.6933 * v.X + 1.24946035807;
Would be better written as
Volume = (v.X - 46.11) / ValumeMaxHigh;
That markedly improves things after trying it out with your code.
In English, what we want is the position of the mouse X relative to the left edge of the slider, normalized by the total width of the track. So that means mouse X minus the left offset divided by the total available width - which you hard code in VolumeMaxHigh (which seems to be the actual width / 100, so this guarantees volume will always be out of 100).
If you had a much more complex graphic, you would want to use a RenderTransform during the mouse move, and set Canvas.Left only on the mouse up, but this is simple enough where performance is not the issue.
Anyway, if you were to consider redoing this I might suggest writing a general purpose slider of your own that is not dependent on any particular dimensions but rather learns its dimensions at runtime through ActualWidth and the like. The source code for WPF is online, specifically for Slider, which will show you how that would be done. Reproducing existing controls in your own coding style is one of the best ways to learn WPF IMO so I'd encourage it as a learning exercise.
You can almost certainly re-template Slider to get what you want too, and if all you want to do is solve the problem at hand and go home that's perfectly fine. But since you put in all this effort already it's worth learning how to do right, as sooner or later you'll come up with a genuine need to write a complex custom control.
Also whether you decide to re-template Slider or make your own, studying the default template for Slider will help too.
It might be interesting to give an idea how how I re template the slider for our brass sliders.
I'll miss out the complicated stuff for the brass teardrop since it's not relevent here.
This is a bit of a dirty approach but I don't need a bunch of functionality in a regular slider.
A slider has a track - the container for everything. In that go two repeatbuttons ( or buttons or whatever you wanted actually ) which kind of look like the track but clicking them moves your pointer.
Then there is the pointer itself which is a thumb. A thumb in wpf is something intended to be dragged.
<ControlTemplate x:Key="BrassSlider" TargetType="Slider">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="1" Fill="Gray"
Stroke="Transparent"
StrokeThickness="1"
Height="13" VerticalAlignment="Center"
Margin="0,0,4,0">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="2"/>
</Rectangle.Effect>
</Rectangle>
<Rectangle Grid.Row="1"
Stroke="Sienna"
StrokeThickness="1"
Height="14" VerticalAlignment="Center"
Margin="0,0,4,0"
Fill="White"
>
</Rectangle>
<Track Grid.Row="1" x:Name="PART_Track"
>
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderDecreaseButtonPlain}" Command="Slider.DecreaseLarge" />
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderIncreaseButtonPlain}" Command="Slider.IncreaseLarge" />
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb Style="{StaticResource SliderThumb}" Grid.ZIndex="30" />
</Track.Thumb>
</Track>
</Grid>
</ControlTemplate>
Thumb, but without any teardrop complicated gubbins.
<Style x:Key="SliderThumb" TargetType="Thumb">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Control Template="{StaticResource TearDropPointer}" Height="40" Width="20" >
<Control.Effect>
<DropShadowEffect />
</Control.Effect>
</Control>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And one of the buttons.
<Style x:Key="SliderDecreaseButtonPlain" TargetType="RepeatButton">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RepeatButton">
<Border SnapsToDevicePixels="True"
Background="Transparent"
BorderThickness="0" Height="14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You could easily make those repeatbuttons any shape you like defined by a geometry. Like you have.
Similarly, you can easily make the thumb an ellipse or whatever you fancy.
One other thing is worth mentioning.
When you see a named part in any reference template like that PART_Track above then that is likely used in the code for the control. If you miss any named parts out then there's a fair chance your control will not behave as you expect.
This slow response can happen also with a regular Slider. If this was the case I would recommend using the "Delay" to the binding of the Slider.
In your case we should do something similar : all mouse events should just keep the mouse point somewhere with no logic and no rendering. Parallelly , create a timer event to occur every 10 milliseconds (or so.. ) , and make the changes there. This way you can improve the system responsiveness.
The code behind may look as following:
Point _lastPoint;
Point _lastPointHandled;
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(10);
timer.Tick += Timer_Tick; ;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (_lastPoint != _lastPointHandled)
{
// do your things
_lastPointHandled = _lastPoint;
}
}
private void SwitchPath_MouseMove(object sender, MouseEventArgs e)
{
_lastPoint = e.GetPosition(VolumeScrollBarCanvas);
}
private void SwitchPath_MouseUp(object sender, MouseButtonEventArgs e)
{
_lastPoint = e.GetPosition(VolumeScrollBarCanvas);
}

Canvas doesn't get pointer events

I can't get why my canvas doesn't get pointer events. Below my code and a part of the XAML layout:
XAML
<Canvas
x:Name="cPad"
Canvas.ZIndex="99"
Grid.Column="0"
PointerPressed="Pad_PointerPressed">
<Rectangle
x:Name="rPicker"
Width="24"
Height="24"
Stroke="Black"
Fill="White"
StrokeThickness="3"/>
</Canvas>
C#
private void Pad_PointerPressed(object sender, PointerRoutedEventArgs e)
{
cPad.CapturePointer(e.Pointer);
var point = e.GetCurrentPoint(cPad).Position;
Canvas.SetLeft(rPicker, point.X);
Canvas.SetTop(rPicker, point.Y);
e.Handled = true;
}
The problem that rPicker moves only if I click on rPicker... But I need to Pad_PointerPressed executes for any point on canvas. How can I make it?
Set Canvas.Background property to Transparent to enable PointerPressed events:
<Canvas
...
Background="Transparent"
>
...
</Canvas>

How can I drag and drop controls using a common method?

I have the following XAML code, which creates two stack panels within a big parent Stack Panel. I would like to be able to drag each small stack panel within the parent bigStack panel.
XAML
<StackPanel BorderThickness="1" BorderBrush="Black" x:Name="bigStack">
<StackPanel x:Name="smallStack1" ManipulationMode="All" ManipulationDelta="objectManipulationDelta" ManipulationStarting="objectManipulationStarting">
<TextBlock Text="John Doe"/>
<TextBlock Text="CEO"/>
</StackPanel>
<StackPanel x:Name="smallStack2" ManipulationMode="All" ManipulationDelta="objectManipulationDelta" ManipulationStarting="objectManipulationStarting">
<TextBlock Text="Jane Doe"/>
<TextBlock Text="CTO"/>
</StackPanel>
</StackPanel>
C# backend:
private TranslateTransform dragtranslation ;
private void objectManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
dragtranslation.X += e.Delta.Translation.X;
dragtranslation.Y += e.Delta.Translation.Y;
}
private void objectManipulationStarting(object sender, ManipulationStartingRoutedEventArgs e)
{
var stackDragged = e.OriginalSource as StackPanel;
dragtranslation = new TranslateTransform();
stackDragged.RenderTransform = this.dragtranslation ;
}
Original Code found here (Official Microsoft UWP Documentation) but adapted (obviously wrongly) to suit my needs
PROBLEM 1
1) Drag smallStack1 for the first time: OK
2) Drag smallStack2 for the second time: Reverts back to the original position
PROBLEM 2
1) Drag smallStack1 for the first time: OK
2) Drag smallStack2 for the first time: OK
3) Drag either of the smallStacks again: Reverts back to the original position
You can check the problems in the .gif below:
WHAT I WISH TO ACCOMPLISH
Drag the controls using a common method, because I plan to dynamically create more controls inside the bigStack panel.
You are basically reinstantiating TranslateTransform everytime you click on an Item. That is the reason why when you click on the item second time, it navigates back to 0,0 which is the original position for TranslateTransform.
To Handle this in a easier way, this is what I would do.
1) I would give explicit TranslateTransform to the smallStackPanel's
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel BorderThickness="1" BorderBrush="Black" x:Name="bigStack">
<StackPanel x:Name="smallStack1" ManipulationMode="All" ManipulationDelta="objectManipulationDelta" >
<StackPanel.RenderTransform>
<TranslateTransform />
</StackPanel.RenderTransform>
<TextBlock Text="John Doe"/>
<TextBlock Text="CEO"/>
</StackPanel>
<StackPanel x:Name="smallStack2" ManipulationMode="All" ManipulationDelta="objectManipulationDelta" >
<StackPanel.RenderTransform>
<TranslateTransform />
</StackPanel.RenderTransform>
<TextBlock Text="Jane Doe"/>
<TextBlock Text="CTO"/>
</StackPanel>
</StackPanel>
</Grid>
And then all i need to do in codebehind is handle ManipulationDelta.
private void objectManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var stackDragged = e.OriginalSource as StackPanel;
(stackDragged.RenderTransform as TranslateTransform).X += e.Delta.Translation.X;
(stackDragged.RenderTransform as TranslateTransform).Y += e.Delta.Translation.Y;
}
Output:
Update
To add TranslateTransform from Code
StackPanel sp = new StackPanel();
sp.RenderTransform = new TranslateTransform();
Good Luck.

Array Binding simple example doesn't work

I'm very new to xaml and I'm trying to understand the Binding issue. I have a problem with the Array Binding. I created this very simple example: I have a stack panel with three images. Each image has a RotationTransform. Each Angle is obtained by an array element (the array is a DependencyProperty called Rotations). This is the xaml simple file:
<StackPanel Orientation="Vertical">
<Image Source="/Assets/knife.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[0], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Image Source="/Assets/fork.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[1], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Image Source="/Assets/spoon.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding ElementName=pageRoot, Path=Rotations[2], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Button x:Name="actionButton" Content="Try Binding!"
Click="Op_Click"/>
</StackPanel>
And this is my c# class:
public sealed partial class MainPage : Page
{
public static readonly DependencyProperty RotationsProperty = DependencyProperty.Register("Rotations", typeof(double[]), typeof(MainPage),
new PropertyMetadata(new double[3]));
public double[] Rotations
{
get { return (double[])GetValue(RotationsProperty); }
set { SetValue(RotationsProperty, value); }
}
private void Op_Click(object sender, RoutedEventArgs e)
{
Rotations[0] = 180;
Rotations[1] = 130;
Rotations[2] = 350;
}
public MainPage()
{
this.InitializeComponent();
Rotations[0] = 20;
Rotations[1] = 90;
Rotations[2] = 180;
}
}
The binding works only the first time (at startup time). When I click on the button (changing the Rotations array) the binding doesn't work and it is completely ignored from my images.
This is a very simple example, so it's clear that I miss something concerning the Binding issue.
I guess the problem is that you change the value of the array entries, but you don't change the array itself, so 'SetValue' does not get called. You could try to set 'Rotations' to a new array.
this.Rotations = new double[] {180, 130, 350};
Edit: I tested your code with my changes and it worked. Another suggestion would be to write a setter method for the array entries and call 'SetValue' or (like suggested in the comments) use 'INotifyPropertyChanged' instead of a DependencyProperty.
Try the below code:
Xaml:
<StackPanel Orientation="Vertical">
<Image Source="/Assets/knife.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding Rotations[0], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Image Source="/Assets/fork.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding Rotations[1], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Image Source="/Assets/spoon.png" Width="50" Height="100" Stretch="Uniform" RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<RotateTransform Angle="{Binding Rotations[2], Mode=OneWay}"/>
</Image.RenderTransform>
</Image>
<Button x:Name="actionButton" Content="Try Binding!"
Click="Op_Click"/>
</StackPanel>
In the code behind set the DataContext as below :
this.DataContext = this;
Ok, I found a solution using ObservableCollection: the xaml file remains the same, but the c# class changes this way:
public sealed partial class MainPage : Page
{
public static readonly DependencyProperty RotationsProperty =
DependencyProperty.Register("Rotations", typeof(ObservableCollection<double>), typeof(MainPage),
new PropertyMetadata(new ObservableCollection<double>()));
public ObservableCollection<double> Rotations
{
get { return (ObservableCollection<double>)GetValue(RotationsProperty); }
set { SetValue(RotationsProperty, value); }
}
private void Op_Click(object sender, RoutedEventArgs e)
{
Rotations[0] = 180;
Rotations[1] = 180;
Rotations[2] = 320;
}
public MainPage()
{
this.InitializeComponent();
Rotations.Add(90);
Rotations.Add(90);
Rotations.Add(90);
}
}

Dynamically adding controls and gesture listener in wp7

I want to add some images or controls dynamically in my canvas control and for each control I want to get its gesture event. How I Would I get that what will be the best approach.
void AddText()
{
TextBlock name = new TextBlock();
name.Text = "This is text " + Count;
Random rnd1 = new Random();
name.Width = rnd1.Next(0, 400);
name.Height = rnd1.Next(0, 800);
var gl = GestureService.GetGestureListener(name);
gl.Tap += new EventHandler<GestureEventArgs>(GestureListener_Tap);
gl.Hold += new EventHandler<GestureEventArgs>(GestureListener_Hold);
canvas1.Children.Add(name);
}
private void GestureListener_Tap(object sender, GestureEventArgs e)
{
MessageBox.Show("I Am Tapped");
}
private void GestureListener_Hold(object sender, GestureEventArgs e)
{
MessageBox.Show("I Am Holded");
}
But in this way my all controls are placed on same place even I used random function for thier width and height. And other thing when I tap on any textblock that i created with this way. It calls all gesture events.
Unlike StackPanel, Canvas control behaves like absolute positioning in HTML/CSS. Each element will be given its own specific location on the page. With elements absolutely positioned, they don’t adjust. Elements will overlap, without having any positioning-related effect on its neighbors.
<Canvas>
<Rectangle Fill="Red" Width="100" Height="100" Canvas.Top="100" Canvas.Left="100" />
<Rectangle Fill="Orange" Width="100" Height="100" Canvas.Top="100" Canvas.Left="200" />
<Rectangle Fill="Green" Width="100" Height="100" Canvas.Top="200" Canvas.Left="100" />
<Rectangle Fill="Blue" Width="100" Height="100" Canvas.Top="200" Canvas.Left="200" />
</Canvas>
For each element in your Canvas, you will need to specify the Canvas.Top and Canvas.Left properties. Omitting these values will result in your elements being positioned in the top left corner of the Canvas, at position 0,0.
So you need to provide Left and Top properties as shown below,
Canvas.SetLeft(name, 50);
Canvas.SetTop(name, 100);

Categories

Resources