I am making a GUI using Windows Presentation Foundation (WPF). When I mouse click a button (left or right), I want a message box shown. So far I have managed to make an example from tutorials, but it only works when I right-click, and not when I left-click the button. I cannot see anything in my code, which should prevent left-click from working, so I hope you can help me.
XAML code
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="72">
Hello, WPF!
</TextBlock>
<!-- This button shuld activate the even MyButton_MouseUp -->
<Button Margin="200,250,200,20" Name="MyButton" MouseUp="MyButton_MouseUp">
Test
</Button>
</Grid>
C# code
// This only works on right-click
private void MyButton_MouseUp(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Hello world!");
}
You can subscribe to the PreviewMouseUp's Tunneled event instead of MouseUp:
<Button Margin="200,250,200,20" Name="MyButton" PreviewMouseUp="MyButton_MouseUp" />
The PreviewMouseUp's Routing strategy is Tunneling, i.e it will go down of the VisualTree hierarchy, and so the Tunnel events are triggered before the Bubble events.
In addition to S. Akbari's post, this one is worth reading in order to understand why right-click works, and left-click does not...
How to use mouseDown and mouseUp on <button/>
Related
I created a UserControl, and added a Button inside it removing the Background and Text properties:
<Button x:Name="Button"
HorizontalAlignment="Center"
Height="40"
VerticalAlignment="Center"
Width="40"
RenderTransformOrigin="0,-2"
Margin="0,0,0,0"
BorderBrush="{x:Null}"
Click="Button_Click"
Background="{x:Null}"/>
I also hadled the Button Click event as below:
private void Button_Click(object sender, RoutedEventArgs e)
{
Button.Content = new cross();
}
The above code fills the Button content with another UserControl which is a simple cross pic.
I have placed the UserControl with the Button into a MainWindow app and after pressing Button, it starts blinking - background is fluently changing between two colours. Beside my functionality from code works good. I just don't know how to get rid of that blinking background.
Before click:
After click:
You could set Focusable="False" at your Button to achive this.
But you should read about the Focusableproperty in the MSDN to check if it's ok for you. I guess you can't focus the Buttonusing the tab key anymore. But maybe that's not a problem for you.
I'm using WPF alongside Caliburn.Micro. I want any code to be run when a label is clicked. I tried some googling and found out about cal:Message.Attach.
XAML:
<Label x:Name="Info" Content="Info" HorizontalAlignment="Left" Margin="305,440,0,0"
VerticalAlignment="Top" FontFamily="Tahoma" FontSize="10" FontWeight="Bold" cal:Message.Attach="[Action ShowAboutWindow()]"/>
C#:
public void ShowAboutWindow()
{
MessageBox.Show("xyz"); // just to test whether ShowAboutWindow is executed whatsoever (see explanation below)
WindowManager.ShowWindow(new AboutViewModel(EventAggregator, WindowManager, SettingsManager));
}
However, ShowAboutWindow isn't run whatsoever. I added a MessageBox to make sure that it isn't the WindowManager screwing it up.
How can I achieve what I desire?
EDIT 1: What I had tried even before was adding a public void Info() method to the ViewModel, as this works for buttons. But it didn't in this case.
Try attaching to the MouseLeftButtonUp event to simulate a click event after the mouse left button is released.
cal:Message.Attach="[Event MouseLeftButtonUp] = [Action ShowAboutWindow()]"
Here I have sample window with a grid. I need to capture event when key is pressed. But it is not raising when I click grid area and then press key. It will work only if Textbox is focused. I know it will work if I capture it from Window. But I have other application with few usercontrols and I need to capture it from distinct ones. I tried to set Focusable.false for Window and true for Grid but it not helps.
Any solutions?
<Window x:Class="Beta.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" Closed="Window_Closed_1" Focusable="False">
<Grid KeyDown="Grid_KeyDown_1" Focusable="True">
<TextBox x:Name="tbCount" HorizontalAlignment="Left" Height="35" Margin="310,49,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="83"/>
</Grid>
Right this is weird. This is clearly a focus problem, still I can not understand why the grid do not take Focus, even when we click on it.
Though there is a workaround: create an handler for the loaded event of the grid:
<Grid x:Name="theGrid" KeyDown="Grid_KeyDown_1" Focusable="True" Loaded="TheGrid_OnLoaded">
And then force focus in your code behind:
private void TheGrid_OnLoaded(object sender, RoutedEventArgs e)
{
theGrid.Focus();
}
Your keydown event will work after that.
Hope it helps.
I had the same issue with a Universal Windows Platform (UWP) app. I attached the event to a grid in XAML but it would only work when the focus was on the TextBox. I found the answer (not just a workaround) on MSDN: https://social.msdn.microsoft.com/Forums/en-US/56272bc6-6085-426a-8939-f48d71ab12ca/page-keydown-event-not-firing?forum=winappswithcsharp
In summary, according to that post, the event won't fire because when focus to the TextBox is lost, it's passed higher up so the Grid won't get it. Window.Current.CoreWindow.KeyDown should be used instead. I've added my event handlers to the page loaded event like this:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
Window.Current.CoreWindow.KeyDown += coreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
}
This works as expected for me.
I tried using the Focus Method too, to no avail, until I set the Focusable property to true ( It was default to False. )
I had the same problem, I've used PreviewKeyDownevent and it worked for me.
I've encountered a weird behavior in WPF. Even though there are quite a few ways to avoid this problem, I'm trying to better understand why it's happening:
I created a new WPF application, just added a button which has a ContextMenu:
<Grid>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
<Button.ContextMenu>
<ContextMenu x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</ContextMenu>
</Button.ContextMenu>
</Button>
</Grid>
In the code behind I use MouseEnter to show the ContextMenu and MouseLeave to hide it:
private void BtnTest_OnMouseEnter(object sender, MouseEventArgs e)
{
myContext.PlacementTarget = btnTest;
myContext.Placement = PlacementMode.Bottom;
myContext.IsOpen = true;
}
private void BtnTest_OnMouseLeave(object sender, MouseEventArgs e)
{
myContext.IsOpen = false;
}
So now - I see the ContextMenu under the button when the mouse is on the button and it hides when the mouse leaves the button.
BUT when I click the button I get an exception
An unhandled exception of type 'System.StackOverflowException'
occurred in WindowsBase.dll
Question is - Why is the Mouse Click, specifically, triggering this exception? I don't have any code of mine running on the Click event, yet without clicking an exception doesn't occur...
BTW: Same will happen if I replace the Button with an Image for instance, so it doesn't seem to be caused by a specific control...
Change your XAML like this:
<Grid>
<Popup x:Name="myContext">
<TextBlock Text="Context Menu Text"></TextBlock>
</Popup>
<Button x:Name="btnTest" Margin="10,10,10,10"
MouseEnter="BtnTest_OnMouseEnter" MouseLeave="BtnTest_OnMouseLeave">
</Button>
</Grid>
I think there is a loop of this sort going on in your code:
you enter the button, the popup shows
you click, popup hides (default behavior of contextmenu)
button gets focus, popup is shown again
What happens if you set the ´StaysOpen´ property of the ContextMenu? If you then dont get this behavior anymore my suspicion is correct.
I am creating a WPF/xaml application with
WindowStyle="None"
So because of this I am having to use
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
// Begin dragging the window
this.DragMove();
To make it so the window can be dragged around the screen. However I also want to make images within the window drag-able which I planned to do using
<Image HorizontalAlignment="Right" Height="65" Width="203" Margin="0,278.271,14.434,82.5" Source="Images/Implementation1.png" Stretch="Fill">
<i:Interaction.Behaviors>
<ei:MouseDragElementBehavior ConstrainToParentBounds="True"/>
</i:Interaction.Behaviors>
</Image>
The issue is that I can't get them both to work on the same window as they will only function if the other is switched off. Any help would be greatly appreciated.
Your OnMouseLeftButtonDown is defined on the whole window, thus interfering with the trigger for MouseDragElementBehavior.
Add a Border to your window, give it a Background (Transparent is ok, just don't leave it without a background) and listen to MouseLeftButtonDown event on the border. Do the DragMove() in the handler for the event.
You can put the border as a title of the window, or you can put it behind the content.