Mouse Event Runs Multiple Times - c#

it's a Rectangle inside a Grid in my program
<Grid x:Name="mainGrid" Background="Transparent" MouseLeftButtonDown="mainGrid_MouseLeftButtonDown">
<Rectangle x:Name="rectangle" MouseEnter="rectangle_MouseEnter" Focusable="True" MouseLeftButtonDown="rectangle_MouseLeftButtonDown" MouseLeave="rectangle_MouseLeave" Fill="#FFF4F4F5" Margin="2" Stroke="Transparent"/>
</Grid>
and mouse left button down events:
private void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("mouse left button down on rectangle");
}
private void mainGrid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("mouse left button down on mainGrid");
}
it's output when mouse button downs on rectangle:
mouse left button down on rectangle
mouse left button down on mainGrid
I want just rectangle mouse event rise up when click in rectangle, and grid mouse event rise up when click outside the rectangle
how can I do that?

MouseLeftButtonDown is bubbling event which means it will go up the visual tree from originating element. You can limit the execution of the handler by setting Handled to true in rectangle_MouseLeftButtonDown
private void rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
Debug.WriteLine("mouse left button down on rectangle");
}

Related

How to click a Button inside of a Button? C# WPF

I created some buttons with another button inside. Then I want to click the inner button but it only throws me the outer button click event, not even both. I tried the solutions in this question but didn't achieve anything. The exact goal that I have is to only load the click method of the inner button when i click it, and if I click in wherever else in the outer button it throws me the respective method.
//Outer button click event
void newBtn_Click(object sender, EventArgs e) {
//Stuff
}
newBtn.Click += new RoutedEventHandler(newBtn_Click);
//Inner button click event
void editButton_Click(object sender, RoutedEventArgs e)
{
//Stuff
editButton.Click += new RoutedEventHandler(editButton_Click);
e.Handled = true;
}
//stuff
It would be better to share your code asking a question.
By the way this sample should work:
<Button Background="Red" Width="100" Height="50" Click="Button_Click">
<Button Background="Green" Margin="10" Width="50" Height="50" Click="Button_Click_1" />
</Button>
In the event handler of the inner button simply add this, as suggested by the post you mentioned:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
e.Handled = true;
}
This will stop the chain of Routed Events (Bubbling and Tunneling)

WPF Grid doesn't fire mouse events when invisible, even though the mouse is capured

In my WPF application I have a Grid with MouseDown, MouseUp and MouseMove events. I want the grid to disappear whenever I press the left mouse button, and reappear when I release it. The problem is that I don't get any mouse events while the grid is invisible (Visibility.Hidden).
This is the MouseDown handler:
private void TabHeaderOnMouseDown(object sender, MouseButtonEventArgs e)
{
tabHeader.CaptureMouse();
tabHeader.Visibility = Visibility.Hidden;
}
And the MouseUp handler:
private void TabHeaderOnMouseUp(object sender, MouseButtonEventArgs e)
{
tabHeader.ReleaseMouseCapture();
tabHeader.Visibility = Visibility.Visible;
}
Setting Opacity to 0 instead of changing the Visibility solved my problem.

Why MouseDown event handler is not getting hit?

I have this very simple button in a WPF that is supposed to call a function preview() on MouseDown, and function hide() on MouseUp. However it's not working and not even hitting its event handler. What is my mistake?
I tried changing the background property, no use. MouseLeave and MouseClick both work but that's not what I want.
XAML:
<Button x:Name="previewButton" Background="#FF383434" Margin="5,5,8,0" MouseDown="previewButton_MouseDown" MouseUp="previewButton_MouseUp" MouseLeave="previewButton_MouseLeave" TouchDown="previewButton_TouchDown" TouchUp="previewButton_TouchUp" TouchLeave="previewButton_TouchLeave" Grid.Row="1" Click="previewButton_Click" Padding="0" >
<StackPanel Height="98" Width="49">
<Image Source="/EZ3D;component/Resources/old/eye.png" Margin="0,17,0,0" />
<TextBlock Text="Preview" TextWrapping="WrapWithOverflow" Margin="0" HorizontalAlignment="Center" Padding="0" FontSize="13" VerticalAlignment="Center"/>
</StackPanel>
</Button>
Code Behind
private void previewButton_TouchDown(object sender, TouchEventArgs e)
{
ShowPreviewImage();
}
private void previewButton_TouchUp(object sender, TouchEventArgs e)
{
HidePreviewImage();
}
private void previewButton_TouchLeave(object sender, TouchEventArgs e)
{
HidePreviewImage();
}
private void previewButton_MouseDown(object sender, MouseButtonEventArgs e)
{
ShowPreviewImage();
}
private void previewButton_Click(object sender, RoutedEventArgs e)
{
ShowPreviewImage();
}
private void previewButton_MouseUp(object sender, MouseButtonEventArgs e)
{
HidePreviewImage();
}
private void previewButton_MouseLeave(object sender, MouseEventArgs e)
{
HidePreviewImage();
}
Handle PreviewMouseDown instead of MouseDown event, PreviewMouseUp instead of MouseUp and so on. It should work for you.
<Button x:Name="previewButton" Background="#FF383434" Margin="5,5,8,0" PreviewMouseDown="previewButton_MouseDown" MouseDown="previewButton_MouseDown" PreviewMouseUp="" MouseUp="previewButton_MouseUp" MouseLeave="previewButton_MouseLeave" TouchDown="previewButton_TouchDown" TouchUp="previewButton_TouchUp" TouchLeave="previewButton_TouchLeave" Grid.Row="1" Click="previewButton_Click" Padding="0" >
<StackPanel Height="98" Width="49">
<Image x:Name="Image1" Source="/EZ3D;component/Resources/old/eye.png" Margin="0,17,0,0" />
<TextBlock Text="Preview" TextWrapping="WrapWithOverflow" Margin="0" HorizontalAlignment="Center" Padding="0" FontSize="13" VerticalAlignment="Center"/>
</StackPanel>
</Button>
All FrameworkElements expose these events. All 'Preview...' events are 'Tunnel' events while the other Mouse events are 'Bubble' events. The tunnel events are raised first on higher level elements, e.g. if you mouse over a button element, the first Preview mouse event goes to the Window and then on down through all of its descendants until it reached the ultimate target, in this case the button. Then the normal, i.e. non-preview' mouse event starts bubbling up from there until it reaches the Window. Anywhere along this chain an event handler can mark the event as handled and stop the process. Here the MouseDown bubbling event gets handled by your textblock placed inside the button.
Certain controls handle input events internally, you usually can use the tunneling version of events (Preview*) in those cases. See MSDN.

How to stop mouse left button function on datagridview c#

Mouse left button should be stop select or click when i edit cell in datagridview. i don't know how to disable mouse left button in windows application.
you can manage the action in MouseClick event:
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
// do something
}
}

How to prevent raise of LostFocus on MouseDown on an control

The question is pretty simple: How do I prevent LostFocus from getting raised on MouseDown on a control that already got focus?
I have the following control (temporary test with all the event bindings):
<Grid Name="gBase" Focusable="True" MouseUp="SetFocus" MouseDown="SetFocus" MouseMove="gBase_MouseMove" PreviewDragEnter="gBase_PreviewDragEnter" LostFocus="gBase_LostFocus" GotFocus="gBase_GotFocus" Background="DarkRed" Width="500" Height="250" />
And the following code behind:
private void SetFocus(object sender, MouseButtonEventArgs e)
{
Grid g = sender as Grid;
g.Focus();
}
private void gBase_LostFocus(object sender, RoutedEventArgs e)
{
Grid g = sender as Grid;
g.Background = Brushes.DarkRed;
}
private void gBase_GotFocus(object sender, RoutedEventArgs e)
{
Grid g = sender as Grid;
g.Background = Brushes.Aquamarine;
}
private void gBase_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Grid g = sender as Grid;
g.Focus();
}
}
private void gBase_PreviewDragEnter(object sender, DragEventArgs e)
{
Grid g = sender as Grid;
g.Focus();
}
The behaviour is almost of that I want to achieve, if I click on the Grid it get focus.
The problem is that if the Grid already got focus it will lose it while I have the mouse button down and not regain it until I release or move. My prefered behaviour would be to prevent that it loses focus in the first place.
The problem was that the parent ScrollViewer stole focus.
This was solved by using the event MouseLeftButtonDown and setting the MouseButtonEventArgs.Handled to true to prevent further handling of the event.
Working code:
<Grid Name="gBase" Focusable="True" MouseLeftButtonDown="SetFocus" LostFocus="gBase_LostFocus" GotFocus="gBase_GotFocus" Background="DarkRed" MinWidth="500" MinHeight="250" Width="500" Height="250" HorizontalAlignment="Left" />
private void SetFocus(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
Grid g = sender as Grid;
g.Focus();
}
Use some property or variable to store which control has actually focus. And after MouseDown compare if control already had focus and if so, then don't do code in LostFocus event.
Important is to update storing property, when focus is changed on other control.

Categories