UWP/c++-cx - Moving a button on the vertical axis by dragging it - xaml

I have a Grid which is as high as the application and has the width of 50. I have got a button in it on the left top with the width of 50 also. I want to move this button along the vertical left axis by dragging it with the mouse. But it should be stil able to be clicked normally. I tried to do this with the drag-and-drop sample by microsoft but the procedure I want to implement is not quite drag-and-drop. How can I implement this by using XAML and c++-cx as code behind in an universal windows app ?
My XAML-Code for the Grid/Button:
<Grid x:Name="Grid1" Width="50" >
<Button x:Name="btnMove" Content="Move me!" Background="PaleGreen" Click="btnMove_Click" VerticalAlignment="Top" HorizontalAlignment="Left" Width="50" Height="50"></Button>
</Grid>

For your requirement, you could move the button on the vertical axis by using ManipulationDelta class. And you could achieve it with the following code.
For more please refer to Handle pointer input. Here is official code sample.
MainPage::MainPage()
{
InitializeComponent();
InitManipulationTransforms();
btnMove->ManipulationDelta += ref new ManipulationDeltaEventHandler(this, &MainPage::btnMove_ManipulationDelta);
btnMove->ManipulationMode = ManipulationModes::TranslateX;
}
void App14::MainPage::InitManipulationTransforms()
{
transforms = ref new TransformGroup();
previousTransform = ref new MatrixTransform();
previousTransform->Matrix = Matrix::Identity;
deltaTransform = ref new CompositeTransform();
transforms->Children->Append(previousTransform);
transforms->Children->Append(deltaTransform);
// Set the render transform on the rect
btnMove->RenderTransform = transforms;
}
void App14::MainPage::btnMove_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
}
void MainPage::btnMove_ManipulationDelta(Platform::Object^ sender, ManipulationDeltaRoutedEventArgs^ e)
{
previousTransform->Matrix = transforms->Value;
// Get center point for rotation
Point center = previousTransform->TransformPoint(Point(e->Position.X, e->Position.Y));
deltaTransform->CenterX = center.X;
deltaTransform->CenterY = center.Y;
// Look at the Delta property of the ManipulationDeltaRoutedEventArgs to retrieve
// the rotation, scale, X, and Y changes
deltaTransform->Rotation = e->Delta.Rotation;
deltaTransform->TranslateX = e->Delta.Translation.X;
deltaTransform->TranslateY = e->Delta.Translation.Y;
}
You could change the scrolling direction of the button by modifying the ManipulationMode of button.
btnMove->ManipulationMode = ManipulationModes::TranslateY;

Related

custom entry box with icon for xamarin form (android,ios)

Entry box should be rounded with an icon to the left or right in it. I'm using the code presented here to create this custom entry.
1. Remove the rectangular border of Entry
Used CustomRender to achieve this.
Forms
public class NoUnderlineEntry : Entry
{
public NoUnderlineEntry()
{
}
}
Android
Set Background to null
public class NoUnderLineEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.Background = null;
}
}
iOS
Set BorderStyle to None
public class NoUnderlineEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.BorderStyle = UIKit.UITextBorderStyle.None;
}
}
2. Placing Image next to Entry
Adding Image and Entry to the same Grid in two columns.
3. Adding Rounded border to the Entry and Image
Add them inside a Frame with CornerRadius.
XAML
<StackLayout>
<Frame
Padding="10, 5, 10, 5"
HasShadow="False"
BorderColor="Gray"
CornerRadius="30">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<local:NoUnderlineEntry/>
<Image Source="icon.png" Grid.Column="1" WidthRequest="50" Aspect="AspectFit"/>
</Grid>
</Frame>
</StackLayout>
UI result:
Please note: I won't present a copy-and-paste-able answer, but rather an outline on how to add the images. You'll have to integrate the code in your solution by yourself.
On iOS
There already is an answered question on how to achieve this with Swift on iOS, you can find it here.
Basically what to do is to set the right view (or left view respectively) on the UITextField from your custom renderer (in OnElementChanged).
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
var imageView = new UIImageView(new CGRect(0, 0, 20, 20));
var image = UIImage.FromFile("ic_location.png");
imageView.Image = image;
this.Control.RightView = imageView;
this.Control.RightViewMode = UITextFieldViewMode.Always;
}
This sets the view in the right of the UITextField to a UIImageView. If you wanted to show the icon before the text instead, you'd have to set LeftView and LeftViewMode instead. This is how it looks like. (I intentionally did not inline the image, because it rendered the answer less redable.)
Of course the file ic_location.png has to be in your platform projects resources.
You may need some fine tuning, but basically that's it.
On Android
The TextView.setCompoundDrawablesWithIntrinsicBounds
Sets the Drawables (if any) to appear to the left of, above, to the right of, and below the text. Use null if you do not want a Drawable there. The Drawables' bounds will be set to their intrinsic bounds. (source)
By loading the icon from the resource and setting it with SetCompoundDrawablesWithIntrinsicBounds (uppercase now, since we're now on C#) you can display the Entry with the icon:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
this.Control.SetCompoundDrawablesWithIntrinsicBounds(null, null, this.GetIcon(), null);
this.Control.CompoundDrawablePadding = 25;
}
private Drawable GetIcon()
{
int resID = Resources.GetIdentifier("ic_location", "drawable", this.Context.PackageName);
var drawable = ContextCompat.GetDrawable(this.Context, resID);
var bitmap = ((BitmapDrawable)drawable).Bitmap;
return new BitmapDrawable(Resources, Bitmap.CreateScaledBitmap(bitmap, 20, 20, true));
}
This is how the Android version looks like.
For showing the icon on left left, pass the drawable to the first parameter instead of the third.

UWP: Content dialog width stays the same

I have tried to set the width and also min height and min width but still the dialogue wont change to full screen. tried window.bounds too but teh dialog wont expand beyond a fixed width.
public sealed partial class ContentDialog1 : ContentDialog
{
public ContentDialog1()
{
this.InitializeComponent();
this.MinWidth = Window.Current.Bounds.Width;
}
private void ContentDialog_PrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
private void ContentDialog_SecondaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{
}
}
}
<ContentDialog
x:Class="PowerUp.UWP.View.ContentDialog1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PowerUp.UWP.View"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="TITLE"
PrimaryButtonText="Button1"
SecondaryButtonText="Button2"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
MinWidth ="2000">
<Grid x:Name="cd1" >
</Grid>
This is what I want
This is how content dialog is shown in my application
It is actually very simple, did a bit research and found the simplest answer, you can keep doing what you were already doing in the first place and just set the FullSizeDesired property of your ContentDialog to true.
Popup
Or you can try it with popup.
var c = Window.Current.Bounds;
var okButton=new Button{Content="Ok"};
okButton.Click += okButtonClicked; // now where you have this okButtonClicked event you can execute any code you want including, closing the popup.
var g = new Grid
{
Width = c.Width,
Height = c.Height,
Background = new SolidColorBrush(Color.FromArgb(0x20, 0, 0, 0)),
Children =
{
new StackPanel
{
Width = 400,
Height = 200,
Background = new SolidColorBrush(Colors.White),
Children=
{
new TextBlock{Text="Title"},
new TextBlocl{Text="description"},
okButton
}
}
}
};
var p = new Popup
{
HorizontalOffset = 0,
VerticalOffset = 0,
Width = c.Width,
Height = c.Height,
Child = g
};
p.IsOpen = true; // open when ready
Notice that Child of popup is g which is a grid, you can put your content within this grid or you can use a StackPanel instead of this grid and then put your contents within that StackPanel, whatever you want to do here is your decision, putting elements in popup is exactly like putting elements in a ContentDialog.
Achieving the same with a simple Grid alongside your frame
<Grid>
<Grid Horizontallignment="Stretch" VerticalAlignment="Stretch" Visibility="Collapsed" x:Name="ContentGrid" canvas.ZIndex="5"><--this grid will act as content dialog, just toggle its visibility to the backend-->
<--put all your content here along with your ok and cancel buttons-->
</Grid>
<Frame/> <--this is the code where you have your frame-->
</Grid>
in above code the frame and your actually content grid will be parallel to each other, and whenever content grid is visible only it will be shown in the app because it has ZIndex greater than 0 and your frame will hide behind it, and whenever its visibility is collapsed it will not be shown and you will be able to see your frame normally.

How do I create a tap moveable control in WinRT?

I wrote a UserControl in WinRT and I want to make it moveable with a finger.
When I move it using a pen or mouse it is still moving but not when i use a finger.
The PointerMoved is not triggert when I use a finger.
Here is the simple xaml:
<UserControl>
<Rectangle PointerPressed="PointerPressed" PointerMoved="PointerMoved"/>
</UserControl>
and here is the code:
private Point position;
void PointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
Rectangle r = sender as Rectangle;
var pointerPoint = e.GetCurrentPoint(r);
position = pointerPoint.Position;
}
void PointerMoved(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
{
Rectangle r = sender as Rectangle;
var delta = e.GetCurrentPoint(r).Position;
r.Margin = new Thickness(r.Margin.Left + delta.X - position.X, r.Margin.Top + delta.Y - position.Y, 0, 0);
}
What do I miss here?
Edit:
I am working with Windows 8.1 and VisualStudio 2013.
Maybe it's a new feature^^
It's simpler than you think!
<Rectangle Width="100" Height="100" Fill="White"
ManipulationMode="TranslateX,TranslateY"
ManipulationDelta="Rectangle_ManipulationDelta_1" />
private void Rectangle_ManipulationDelta_1(object sender, ManipulationDeltaRoutedEventArgs e)
{
var _Rectangle = sender as Windows.UI.Xaml.Shapes.Rectangle;
var _Transform = (_Rectangle.RenderTransform as CompositeTransform)
?? (_Rectangle.RenderTransform = new CompositeTransform()) as CompositeTransform;
_Transform.TranslateX += e.Delta.Translation.X;
_Transform.TranslateY += e.Delta.Translation.Y;
}
Best of luck!
First, don't sure you can move by pen or mouse because in PointerMoved event you should check the e.Pointer.IsInContact boolean value to ensure you are selected the object when moving. It make your moving action looks better.
Second, Sorry that I don't know why in your machine the PointerMoved is not triggered when uses finger. Anyway it will better if you set the name of your handler function not same as event name.
If you can share more information, we can discuss.

Image rotation as animation

I am making a Windows 8 application in visual studio 2012 c#.
I am having an image '1.png' and I want to rotate it at any angle as an animation along its center point.
But i want to do it with the help of c# code rather than XAML code.
Thank You in Advance.
In your XAML, have the following image:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Image Source="/Assets/Logo.png" Width="300" RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<RotateTransform x:Name="rotateTransform"/>
</Image.RenderTransform>
</Image>
</Grid>
Then, in code, write the following when you want to animate (you create the Storyboard programmatically, then add to it a relevant Timeline. Note that you can also create the RotateTransform in code if you want.
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await Task.Delay(500);
Storyboard board = new Storyboard();
var timeline = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(timeline, rotateTransform);
Storyboard.SetTargetProperty(timeline, "Angle");
var frame = new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(1), Value = 360, EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut } };
timeline.KeyFrames.Add(frame);
board.Children.Add(timeline);
board.Begin();
}
This will rotate the object 360 degrees.
BTW: I am writing a set of posts that show an even better way of animating. It's not done yet, but it will give you a general idea on how to get a framework for certain types of animations..
First part of the series
Thanks Shahar! I took your example and made a custom control. It's actually an infinite spinning of one ring image.
Spinner.xaml:
<UserControl x:Class="MyControls.Spinner"
...
<Grid >
<Image Source="/Assets/Images/spinner.png" Width="194" RenderTransformOrigin="0.5, 0.5">
<Image.RenderTransform>
<RotateTransform x:Name="rotateTransform"/>
</Image.RenderTransform>
</Image>
</Grid>
</UserControl>
Spinner.cs:
namespace MyControls
{
public partial class Spinner: UserControl
{
public Spinner()
{
InitializeComponent();
this.Loaded += Spinner_Loaded;
}
private void PlayRotation()
{
Storyboard board = new Storyboard();
var timeline = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(timeline, rotateTransform);
Storyboard.SetTargetProperty(timeline, new PropertyPath("(Angle)"));
var frame = new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromSeconds(5), Value = 360, EasingFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut } };
timeline.KeyFrames.Add(frame);
board.Children.Add(timeline);
board.RepeatBehavior = RepeatBehavior.Forever;
board.Begin();
}
private async void Spinner_Loaded(object sender, RoutedEventArgs e)
{
PlayRotation();
}
}
}
Then when you want to use Spinner in another xaml, it's very simple:
Just add a line for it inside any Grid etc:
<include:Spinner/>
(of course you need to define include as something like:
xmlns:include="MyControls"
on top of your xaml)

WP7 dragging a pushpin on a map

Does anyone have any insight into how to implement a draggable pushpin on a map on a WP7 client running Mango? I have a pushpin bound to a geo-location on a map and I want the user to be able to drag it on a map and record its new location. I've seen some resources, but they're for non-WP7 Bing Maps control. Any help would be appreciated.
Thanks!
e.GetPosition(element) gives the position relative to the element passed on the parameter. Also, the point to convert using ViewportPointToLocation has to be relative to the position of the map. So, you have to do the following:
Pushpin myPin = sender as Pushpin;
Point p = e.GetPosition(**Map**);
g = Map.ViewportPointToLocation(p);
I know this is a late response but I was working on a similar project and using a similar approach, so I thought I'd share. The approach that I used was:
Create two global double variables to hold X,Y coord's:
double mapLocX;
double mapLocY;
Set these global doubles to the location of the point of your pushpin in your DragStarted event:
Point point = myMap.LocationToViewportPoint(myPin.Location);
mapLocX = point.X;
mapLocY = point.Y;
In your dragDelta event, change these variables as your would your pushpin:
mapLocX += e.HorizontalChange;
mapLocY += e.VerticalChange;
Now on DragCompleted create a new point that takes in our rendered global variables, and map them to a geocoordinate, and here's the kicker; Remove our old pin from the ObservableCollection (Mine is Locations) and add in a new pushpin at our new coordinate:
Point point = new Point(mapLocX, mapLocY);
GeoCoordinate geoCoord = new GeoCoordinate();
geoCoord = myMap.ViewportPointToLocation(point);
Locations.Remove(myPin.Location);
Locations.Add(geoCoord);
Hope this helps
If anyone is curious, this is the solution I came up with:
XAML:
<map:Map x:Name="Map" Height="400" HorizontalAlignment="Left" Margin="6,10,0,0" VerticalAlignment="Top" Width="444" ZoomLevel="19" >
<map:Map.Mode><map:AerialMode /></map:Map.Mode>
<map:Pushpin x:Name="Pin" Background="Green" IsHitTestVisible="True" IsEnabled="True">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DragDelta="Pushpin_OnDragDelta" DragStarted="Pushpin_OnDragStarted" DragCompleted="Pushpin_OnDragCompleted">
</toolkit:GestureListener>
</toolkit:GestureService.GestureListener>
<map:Pushpin.RenderTransform>
<TranslateTransform></TranslateTransform>
</map:Pushpin.RenderTransform>
</map:Pushpin>
</map:Map>
.cs:
private void Pushpin_OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
Pushpin myPin = sender as Pushpin;
TranslateTransform transform = myPin.RenderTransform as TranslateTransform;
transform.X += e.HorizontalChange;
transform.Y += e.VerticalChange;
}
private void Pushpin_OnDragStarted(object sender, DragStartedGestureEventArgs e)
{
Map.IsEnabled = false; // prevents the map from dragging w/ pushpin
}
private void Pushpin_OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
{
Map.IsEnabled = true;
}
Does anyone have any ideas on how to extract the geocoordinates of the pushpin's new location?? I tried the code below in the event handler and it doesn't give correct coordinates:
Pushpin myPin = sender as Pushpin;
Point p = e.GetPosition(myPin);
g = Map.ViewportPointToLocation(p);
myPin.location gives the old coordinates
You want to have the origin of your UI element not your finger right? Try this:
Point pM = e.GetPosition(**Map**);
Point pE = e.GetPosition(**UIElement**);
Point origin = new Point(pM.X - pE.X, pM.Y - pE.Y);
GeoCoordinate g = Map.ViewportPointToLocation(origin);