Move ToolTip in WinRT - c#

In WinRT (Windows Store Apps), I create a tooltip and set it to an element like this:
dragTip = new ToolTip();
dragTip.Content = "Test";
ToolTipService.SetToolTip(element as DependencyObject, dragTip);
dragTip.IsOpen = true;
I want to move this ToolTip as the mouse moves. Is there a way to do that? Or another alternative? I want to show a hint to the user as he/she drags an element.
Update
Here's the approach I took based on #Sajeetharan's suggestion:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" PointerMoved="homeGrid_PointerMoved" x:Name="homeGrid">
....
<GridView x:Name="content" CanDragItems="True" DragItemsStarting="content_DragItemsStarting">
...
</GridView>
<Popup Name="DeepZoomToolTip">
<Border CornerRadius="1" Padding="1" IsHitTestVisible="False">
<TextBlock Text="Here is a tool tip" />
</Border>
</Popup>
....
</Grid>
private void content_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
DeepZoomToolTip.IsOpen = true;
}
private void homeGrid_PointerMoved(object sender, PointerRoutedEventArgs e)
{
var position = e.GetCurrentPoint(homeGrid).Position;
DeepZoomToolTip.HorizontalOffset = position.X;
DeepZoomToolTip.VerticalOffset = position.Y;
}
Notice that the tooltip will move but not when the item is being dragged.

You can do this by using a popup control , Here is the full Thread how to make tooltip move along with mouse
XAML:
<Canvas x:Name="LayoutRoot" Background="White">
<Image Source="/sam.png" MouseMove="Image_MouseMove" MouseLeave="Image_MouseLeave"/>
<Popup Name="DeepZoomToolTip">
<Border CornerRadius="1" Padding="1" IsHitTestVisible="False">
<TextBlock Text="Here is a tool tip" />
</Border>
</Popup>
</Canvas>
private void Image_MouseMove(object sender, MouseEventArgs e)
{
DeepZoomToolTip.IsOpen = true;
DeepZoomToolTip.HorizontalOffset = e.GetPosition(LayoutRoot).X;
DeepZoomToolTip.VerticalOffset = e.GetPosition(LayoutRoot).Y;
}
private void Image_MouseLeave(object sender, MouseEventArgs e)
{
DeepZoomToolTip.IsOpen = false;
}

Related

WPF TextBox with popup

I'm working with WPF Popup. A popup contains some keyboard.
I want to open a popup when a user clicks on a text box and do not hide a popup while textbox has the focus.
Also I need to hide a popup when a user clicks somewhere away from a popup.
Here's the xaml code:
<Grid>
<StackPanel>
<TextBox x:Name="textBox" GotKeyboardFocus="textBox_GotFocus" MouseDown="textBox_MouseDown" />
<Popup x:Name="popup" Width="100" Height="100" PlacementTarget="{Binding ElementName=textBox}" Placement="Bottom"
StaysOpen="{Binding ElementName=text,Path=IsKeyboardFocused}">
<Grid Background="Blue">
</Grid>
</Popup>
</StackPanel>
</Grid>
Here's the c# code:
private void textBox_GotFocus(object sender, KeyboardFocusChangedEventArgs e)
{
popup.IsOpen = true;
}
private void textBox_MouseDown(object sender, MouseButtonEventArgs e)
{
popup.IsOpen = true;
}
I found that the binding can help:
StaysOpen="{Binding ElementName=,Path=IsKeyboardFocused}"
But the TextBox never hides. Also if I set StaysOpen="False" the TextBox never shows
You could handle the LostKeyboardFocus event and check whether the new focused element is the TextBox itself or if it's a child element of the Popup:
private void textBox_GotFocus(object sender, KeyboardFocusChangedEventArgs e)
{
popup.IsOpen = true;
}
private void textBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
var newFocusedElement = e.NewFocus as DependencyObject;
//if the focused element is a child of the window, it can't be the child of the popup
if (newFocusedElement == null || FindParent<Window>(newFocusedElement) != null)
popup.IsOpen = false;
}
private void popup_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
popup.IsOpen = e.NewFocus == textBox;
}
private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null) return null;
var parentT = parent as T;
return parentT ?? FindParent<T>(parent);
}
Sample XAML:
<StackPanel>
<TextBox x:Name="textBox" GotKeyboardFocus="textBox_GotFocus" LostKeyboardFocus="textBox_LostKeyboardFocus" />
<Popup x:Name="popup" Width="100" Height="100" PlacementTarget="{Binding ElementName=textBox}"
LostKeyboardFocus="popup_LostKeyboardFocus"
Placement="Bottom">
<Grid x:Name="popupRoot" Background="Blue">
<TextBox Margin="10" />
</Grid>
</Popup>
<TextBox />
</StackPanel>

Capture Click event of button with image in WPF

I'm new to WPF and created a draggable button with an image inside - which works nicely...but I can't seem to capture the onClick of the button which contains the image?
<Window x:Class="PAD.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:PAD"
mc:Ignorable="d"
Title="C2D" Height="134" Width="134" WindowStyle="None" Background="Transparent" Foreground="Transparent" BorderBrush="Transparent" BorderThickness="0" ResizeMode="NoResize" AllowsTransparency="True">
<Grid x:Name="ClickIcon" Background="Transparent" >
<Button x:Name="dialButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="130" Height="130" Foreground="Transparent" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" >
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="Transparent"/>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image x:Name="phoneIcon" Width="128" Height="128" Source="c:\users\chapmd1\documents\visual studio 2015\Projects\PAD\PAD\red-phone-icon_300205.png" MouseDown="image_MouseDown" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
private void image_MouseDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}
I tried the onClick on the Button, but nothing got captured?
Not sure what you want to achieve, but in case you want to Drag the Window while the button is pressed and then afterwards do something else then you can do it like this:
private void image_MouseDown(object sender, MouseButtonEventArgs e)
{
while (e.ButtonState == MouseButtonState.Pressed)
{
this.DragMove();
Debug.WriteLine("Dragged!");
}
var image = sender as Image;
object parent = FindParent(image);
while (parent != null && parent.GetType() != typeof(Button))
{
parent = FindParent((FrameworkElement)parent);
}
var bt = parent as Button;
if(bt != null)
bt.ClickMode = ClickMode.Press;
}
private void DialButton_OnClick(object sender, RoutedEventArgs e)
{
Debug.WriteLine("Clicked!");
}
DependencyObject FindParent(FrameworkElement ui)
{
return ui.TemplatedParent;
}
}
Your problem is probably somewhere else. This works as expected:
XAML:
<Grid x:Name="ClickIcon" Background="Transparent" >
<Button
Click="dialButton_Click"
x:Name="dialButton"
HorizontalAlignment="Left"
VerticalAlignment="Top" Width="130" Height="130"
Foreground="Transparent"
Background="Transparent"
BorderThickness="0"
BorderBrush="Transparent">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid >
<Ellipse Fill="Transparent"/>
<ContentPresenter
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Image x:Name="phoneIcon"
Width="128" Height="128"
Source="..."
MouseDown="phoneIcon_MouseDown"/>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
C#:
private void phoneIcon_MouseDown(object sender, MouseButtonEventArgs e)
{
System.Diagnostics.Trace.WriteLine("phoneIcon_MouseDown");
}
private void dialButton_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Trace.WriteLine("dialButton_Click");
}

How can change position of canvas in WPF?

How can change runtime position of a canvas in which dynamically I added controls like (labels, lines)?
I can zoom canvas with all controls but I can't move in another position with MouseMove, MouseUp, MouseDown.
<Canvas Name="canvas" Width="1000" Height="400"
Margin="100 0 0 50"
Background="White"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
MouseWheel="Canvas_MouseWheel"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp"
MouseDown="Canvas_MouseDown">
<Canvas.RenderTransform>
<ScaleTransform x:Name="st" />
</Canvas.RenderTransform>
</Canvas>
I find this code in internet but for my case is not working
bool activated;
Point point;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
activated = true;
point = Mouse.GetPosition(canvas);
Mouse.Capture(canvas);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (activated)
{
double top = Canvas.GetTop(canGraph) + Mouse.GetPosition(canvas).Y - point.Y;
Canvas.SetTop(canvas, top);
double left = Canvas.GetLeft(canvas) + Mouse.GetPosition(canvas).X - point.X;
Canvas.SetLeft(canvas, left);
point = Mouse.GetPosition(canvas);
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
activated = false;
Mouse.Capture(null);
}
Edit - The previous solution that I provided was not going to work after the first move of the element without more code so here's a better one
In order to be working correctly the canvas element have to be aligned to the coordinate system of it's parent, which we achieve as we put the canvas in top left corner, if you don't put it there you have to calculate the difference yourselve.
Code behind
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
canvas.CaptureMouse();
}
Stopwatch sw = new Stopwatch();
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (canvas.IsMouseCaptured)
{
translate.X = e.GetPosition(container).X;
translate.Y = e.GetPosition(container).Y;
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
canvas.ReleaseMouseCapture();
}
XAML
<Grid Background="Green" x:Name="container">
<Canvas Name="canvas" Width="100" Height="100"
Margin="0 0 0 0"
Background="Purple"
VerticalAlignment="Top"
HorizontalAlignment="Left"
MouseMove="Canvas_MouseMove"
MouseDown="Canvas_MouseDown">
<StackPanel Background="White">
<TextBlock >asdasda</TextBlock>
<TextBlock >cccc</TextBlock>
<TextBlock >aaaaa</TextBlock>
<TextBlock >bbbb</TextBlock>
</StackPanel>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st" />
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
Original answer
XAML
I'd do something like this:
Add a translate transform and to keep you previous transform put it in a group
Use translate transform in order to move the canvas with positions from the mouse events
For starting point of your translations you can use coordinates in the container
Code behind:
bool activated;
Point point;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
activated = true;
point = e.GetPosition(container);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (activated)
{
translate.X = e.GetPosition(container).X - point.X;
translate.Y = e.GetPosition(container).Y - point.Y;
}
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
activated = false;
}
XAML
<Canvas Name="canvas" Width="100" Height="100"
Margin="0 0 0 0"
Background="Purple"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp"
MouseDown="Canvas_MouseDown">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="st" />
<TranslateTransform x:Name="translate" />
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</Grid>
After mouse down then again I move the canvas is start to move from first position when is been.
P.s.
I add this for more stable code , but always return back to the first position
private void Canvas_MouseLeave(object sender, MouseEventArgs e)
{
activated = false;
}

DoubleTapped Event not working on WebView

I have a WebView control which works fine, but when trying to attach the DoubleTapped Event to the control it doesn't seem to work when I physically go ahead and Double Tap on the web content in the emulator. Is there something that needs to be done?
My XAML:
<Grid x:Name="LayoutRoot" DataContext="{StaticResource FeedEntryModel}">
<WebView x:Name="feedEntry" IsHitTestVisible="True" DefaultBackgroundColor="WhiteSmoke" DoubleTapped="feedEntry_DoubleTapped" IsDoubleTapEnabled="True" IsTapEnabled="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsHoldingEnabled="True" />
</Grid>
The Event Handler
private void feedEntry_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
feedEntry.Navigate(new Uri("http://www.google.com"));
}
Any ideas?
window.document.ondblclick = function() {
window.external.notify("dblclick");
}
private void OnScriptNotify(object sender, NotifyEventArgs e)
{
if (e.Value == "dblclick")
{
}
}
It's because WebView content picks up the double tap. How about trying something like this:
<Grid x:Name="LayoutRoot">
<WebView x:Name="feedEntry" Source="http://igrali.com" IsHitTestVisible="True" DefaultBackgroundColor="WhiteSmoke" IsDoubleTapEnabled="True" IsTapEnabled="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsHoldingEnabled="True" />
<Grid DoubleTapped="feedEntry_DoubleTapped"
Background="Transparent"/>
</Grid>

creating multiple panels and displaying one panel on button click in wpf

I am new to WPF and I want to create a WPF application with 5buttons. On the click of each button I want a content to be displayed on another panel. Right now I just want different images to be displayed on my right side panel on the button clicks.
Here's my XAML code:
<Window x:Class="GridButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MyFirstApp" Height="350" Width="525" Loaded="Window_Loaded">
<Viewbox Stretch="Fill" StretchDirection="Both">
<DockPanel>
<StackPanel DockPanel.Dock="left" Margin="5" Width="Auto" VerticalAlignment="Center" Height="Auto">
<Button Content="1" Name="button2" Click="button2_Click">
</Button>
<Button Content="2" Name="button1" Click="button1_Click_1">
</Button>
<Button Content="3" Name="button3" Click="button3_Click">
</Button>
<Button Content="4" Name="button4" Margin="5">
</Button>
<Button Content="5" Name="button5" Margin="5" Click="button5_Click_1">
</Button>
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Image Name="img1" Source="Blue Hills.jpg" Stretch="Uniform" Visibility="Hidden" ImageFailed="Image_ImageFailed" Height="257" />
</StackPanel>
</DockPanel>
And my xaml.cs file contains code to display image:
private void button2_Click(object sender, RoutedEventArgs e)
{
img1.Visibility = Visibility.Visible;
}
I could get only this far.
You can set the Source property of the Image control in code:
private void buttonx_Click(object sender, RoutedEventArgs e)
{
string path = ... // path to image file here
img1.Source = new BitmapImage(new Uri(path));
}
You could easily reuse the same Click handler for all Buttons and check which one was pressed:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
string path = null;
if (button == button1)
{
path = ... // path to image file 1 here
}
else if ...
if (path != null)
{
img1.Source = new BitmapImage(new Uri(path));
}
}
If you want to remove the a child Panel (or other control) from a parent Panel and add another one, you would have to modify the Panel's Children property:
<StackPanel Name="parent">
<StackPanel Name="child" />
</StackPanel>
parent.Children.Remove(child);
parent.Children.Add(...); // some other control here
This approach would usually make sense if you wanted to create child panels dynamically. If you want to declare everything in XAML you may put all child panels in a Grid and change their visibility as you did already.
However, you might also change the ZIndex attached property.
<Grid>
<StackPanel Name="child1">
</StackPanel>
<StackPanel Name="child2">
</StackPanel>
<StackPanel Name="child3">
</StackPanel>
</Grid>
child3 is topmost by default, but now you can set ZIndex to some value > 0 to make another child topmost:
private void Button_Click(object sender, RoutedEventArgs e)
{
...
// reset ZIndex on previous topmost panel to 0 before
Panel.SetZIndex(child1, 1);
}
Or completely omit the Button/Grid/Panel design and use a TabControl.

Categories