Button Click Not Recognized on Canvas - wpf

Hi I have the following code, I am drawing a button on a canvas with a button template, when I click on the button I want a message to show up, but it doesn't, even when I register a mouse down event on the button it is still not recognized.
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Button r = e.Source as Button;
if (r != null)
MessageBox.Show(r.ToString());
Point mousePoint = Mouse.GetPosition(mainCanvas);
Button button1 = new Button();
button1.Template = (ControlTemplate)this.FindResource("nodeTemplate");
Canvas.SetTop(button1, mousePoint.Y);
Canvas.SetLeft(button1, mousePoint.X);
mainCanvas.Children.Add(button1);
}
}
<Window.Resources>
<ControlTemplate x:Key="nodeTemplate" TargetType="Button">
<Grid>
<Ellipse x:Name="outerCircle" Fill="Red" Height="50" Width="50"/>
<Ellipse x:Name="innerCircle" Fill="Green" RenderTransformOrigin=".5,.5">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX=".9" ScaleY=".9"/>
</Ellipse.RenderTransform>
</Ellipse>
</Grid>
</ControlTemplate>
</Window.Resources>
<DockPanel>
<Canvas x:Name="mainCanvas" Background="Transparent" MouseLeftButtonDown="Canvas_MouseLeftButtonDown">
</Canvas>
</DockPanel>

The MouseLeftButtonDown is marked as handled by the Button, the event will not reach the canvas, use PreviewMouseLeftButtonDown instead (as they use different routing strategies this event cannot be intercepted by the Button because it is raised on the Canvas first). Alternatively you can attach the event ButtonBase.Click to the Canvas, this of course only registers Button-clicks.

Related

Detect mouse left button down (Click) outside a border WPF MVVM

I have a border in MVVM. What I am trying to achieve is to detect mouse left button down outside the border and then hide it. I can do it within the MouseLeftButtonDown event for main window, but I do not know if it is the best solution. How could I do this? I want to avoid this click to interfere with other events, for example, this border is placed in a stackpanel and the stackpanel is being hidden on mouse left button double click.
<Border Grid.Row="2"
x:Name="customPopup"
CornerRadius="10,10,0,0"
Height="25" Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="Auto"
BorderBrush="DarkBlue"
BorderThickness="1"
Background="AntiqueWhite">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Image Source="/Common.Images;component/Images/Info.png"
Height="20"
Width="20" Stretch="Fill"/>
<TextBlock Margin="5"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Background="Transparent"
FontSize="12">
<Run Text="Click outside to close it"/>
</TextBlock>
</StackPanel>
</Border>
Using MouseDown on the window is probably your best bet to get your desired results. You'll need to do some calculations in order to see if the cursor is outside of the border. Something like:
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
// get positions
Point mouseLoc = Mouse.GetPosition(null);
Point borderLoc = customPopup.TranslatePoint(new Point(0,0), null);
// check if the mouse is outside the border
if((mouseLoc.X < borderLoc.x || mouseLoc.X > (borderLoc.X + customPopup.ActualWidth)) && (mouseLoc.Y < borderLoc.Y || mouseLoc.Y > borderloc.Y + customPopup.ActualHeight))
{
// hide the border
}
}
Then to handle the double click, use PreviewMouseDoubleClick. Since Preview events are tunneling rather than bubbling, the double click should get called even if you have a single click event on the same element.
private void Window_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// double click code...
e.Handled = true;
}

WPF Popup disappear on Custom contextmenu opening

I have a TextBox in a PopUp. On clicking a ToggleButton, the PopUp Window opens.
Toggle Button Code
<ToggleButton Name="popupButton" Content="Click Me To Open Popup!" >
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<Border Name="bg" RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased" Background="Transparent" Width="17" Height="15">
<StackPanel HorizontalAlignment="Right" Width="17" >
<Path RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased" Data="M186,52 C208,52 230,52 252,52" Fill="Black" Margin="0,1.5" Stretch="Fill" Stroke="#457faa" StrokeThickness="2" />
<Path RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased" Data="M186,52 C208,52 230,52 252,52" Fill="Black" Margin="0,1.5" Stretch="Fill" Stroke="#457faa" StrokeThickness="2" />
<Path RenderOptions.BitmapScalingMode="HighQuality" RenderOptions.EdgeMode="Aliased" Data="M186,52 C208,52 230,52 252,52" Fill="Black" Margin="0,1.5" Stretch="Fill" Stroke="#457faa" StrokeThickness="2" />
</StackPanel>
</Border>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
On clicking the ToggleButton it will open following the PopUp Window which contains the TextBox.
Popup Window Code
<Popup Name="testPopup" Placement="Bottom" PlacementTarget="{Binding ElementName=popupButton}" IsOpen="{Binding IsChecked, ElementName=popupButton}" StaysOpen="False">
<StackPanel Orientation="Horizontal">
<Label Content="Username: " Background="White"/>
<TextBox Text="Please RightClick to copy the text." ContextMenuOpening="TextBox_ContextMenuOpening">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Copy"/>
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
</StackPanel>
</Popup>
When a user clicks on the TextBox in the PopUp I want to call the ContextMenu opening event which is as following:
CodeBehind for ContextMenuOpening Event
private void OpenContextMenu(FrameworkElement e)
{
if (e.ContextMenu != null)
{
e.ContextMenu.IsOpen = true;
}
}
private void TextBox_ContextMenuOpening(object sender, ContextMenuEventArgs e)
{
e.Handled = true;
this.OpenContextMenu(sender as FrameworkElement);
}
Purpose to Call ContextMenuOpening
I'm calling its opening event because I want to stop the parent contextmenu to open by e.Handled = true. Then I want to open the ContextMenu of the TextBox (source element). Here comes the issue.
Issue
As soon as I open the ContextMenu from code-behind, it opens the ContextMenu but the PopUp disappears as StayOpen property is set to False. I want to use StayOpen to False, as it should close as soon as the focus is lost.

how to access the grids on silverlight

I have a button called test button an when I click on it I want to show a grid whose visbility is set to 0
I created a mouse button event (below) but my Grid (testGrid) is not available in the project.
private void testButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
testGrid.Opacity = 1;
}
it highlights testGrid red
new to SL so not sure whats going on here
** EDIT **
xml for the Grid
<Grid x:Name="testGrid" HorizontalAlignment="Left" Width="150" Margin="950,-77,0,0" Height="77" VerticalAlignment="Top" Opacity="0">
</Grid>
<Image x:Name="testButton" HorizontalAlignment="Right" Margin="0,1,180,3" Stretch="Fill" Width="53" Height="49" Cursor="Hand" Opacity="0.8" >
The reason that your grid might not be accessibly in the .cs file is if you have changed the class name in the .cs file, but not in the Xaml directive at the top of your .xaml file.
If these two mis match, visual studio won't be able to link up the two files and so you wouldn't be able to see the grid control in the code behind.
Other items with your code to consider:
Though Opacity will work an alternative I use more often is:
This will show the grid.
testGrid.Visibility = Visibility.Visible;
This will hide the grid.
testGrid.Visibility = Visibility.Collapsed;
Also, Your "Button" is an Image tag and not a button. It is an image with the same name as the method you are trying to call. You will either need to change your Image to allow for an on click event or change it to a button, something like
<Button Click="TestBUtton" Text="MyButton" />
And I'd enter that in the Xaml directly so that when you type in the click event handler it auto generates the method in the code behind for you.
try this:
On XAML
<Grid x:Name="testGrid" HorizontalAlignment="Left" Width="150" Margin="950,-77,0,0" Height="77" VerticalAlignment="Top" Opacity="0">
</Grid>
<Image x:Name="testButton" HorizontalAlignment="Right" Margin="0,1,180,3" Stretch="Fill" Width="53" Height="49" Cursor="Hand" Opacity="0.8" MouseLeftButtonDown="testButton" />
on the cs
private void testButton(object sender, System.Windows.Input.MouseButtonEventArgs e){
testGrid.Visibility = Visibility.Visible;
}

WPF Popup control on ImageMouseLeftButtonDown disappears immediately

I have a popup defined as follows,
<Popup x:Name="popLines"
Placement="Bottom"
IsOpen="False"
Width="145" Height="42"
StaysOpen="False"
PopupAnimation="Fade"
AllowsTransparency="True"
HorizontalOffset="-2" VerticalOffset="0">
<Grid Margin="2">
<Path StrokeThickness="0.7" StrokeLineJoin="Round" Fill="#FFFFFFFF" Stretch="Fill" Stroke="Black" Data="M6.5,0.5 L30.167,0.5 30.167,8.4999992 190.16701,8.4999992 190.16701,44.166001 0.5,44.166001 0.5,8.4999992 6.5,8.4999992 6.5,0.5 z">
</Path>
<Grid>
<StackPanel Orientation="Horizontal">
<TextBox BorderBrush="Black" BorderThickness="0.5" Margin="5,10,2,2" Width="110" Height="20" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ToolTip="Excel File Path"></TextBox>
<Image Source="/App_Desktop;component/Resources/save.png" Margin="2,10,5,2" Width="16" Height="16"></Image>
</StackPanel>
</Grid>
</Grid>
</Popup>
I set IsOpen=true when an image MouseLeftButtonDown event fires.Except, the popup disappears as soon as it appears. What is going wrong?
I think what happens is, that the the MouseLeftButtonUp event fires while the Mouse is not over the Popup. Try holding the mousebutton down and move your mouse so it is above the popup to see if it stays open, and then release the mousebutton.
you can solve this by setting StaysOpen="True" or by setting IsOpen=true in a click eventhandler or MouseButtonUp eventhandler.
Also using your example with the image, you could have a transparent area right above the image in your popup visualtree that 'captures' the MouseUp event when the popup is open. you would have to change the placement option and bind that area to the image's width and height properties.

Silverlight MouseLeave showing inconistent behaviour

So, my problem is that the MouseLeave event only gets triggered if I move my cursor at a certain speed. Below is a Thumb with a Border. Click the thumb and keep the mouse button down. Move slowly outside the border = no event, Move fast outside the border = event.
<Grid x:Name="LayoutRoot" Background="White">
<Border BorderBrush="Black" BorderThickness="3" Width="200" Height="100"
MouseLeave="Border_MouseLeave">
<Thumb />
</Border>
</Grid>
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
MessageBox.Show("Border_MouseLeave");
}
Is it a bug in silverlight or am I missing something?
Thanx
/Mike
Thanx for the anwers, here's an update:
It seems to have something to do with MouseCapture as Guy suggests. The reason being that I also get the problem using Button or a Rectangle that captures the mouse in code-behind.
If I put a Grid between the Thumb and the Border the problem disappears so I think I will go with that.
I also noticed a related problem as I played around some.
<Grid Width="200" Height="100" Background="Transparent"
MouseLeave="Border_MouseLeave">
<Button />
<Rectangle Width="40" Height="40" Fill="Violet"
HorizontalAlignment="Left" />
</Grid>
If I press the left button and move the cursor to the left over the Rectangle and out the MouseLeave event is not registered.
This is all very strange.

Resources