I have a problem with bubbeling events. I manage to bubble events in borders, grid, stackpanel, but not in a ScrollViewer
If you look at the example below you will notice that when you click the TextBlock the event is bubbeled up to the Grid. But when I include the ScrollViewer the event stops here and is not sent up to the Grid.
Does anyone now whay this happends and if it can be fixed? I really need to be able to bubble events through a ScrollViewer as I use it all the time.
<Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<!--<ScrollViewer MouseLeftButtonDown="ScrollViewer_MouseLeftButtonDown">-->
<StackPanel Orientation="Vertical" MouseLeftButtonDown="StackPanel_MouseLeftButtonDown">
<TextBlock Text="Click me to bubble an event" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
</StackPanel>
<!--</ScrollViewer>-->
</Grid>
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("LayoutRoot clicked");
}
private void ScrollViewer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("ScrollViewer clicked");
e.Handled = false;
}
private void StackPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("StackPanel clicked");
e.Handled = false;
}
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("Textblock clicked");
e.Handled = false;
}
}
use AddHandler(yourDelegate, True); syntax for adding event handlers, which will ignore Handled flag set by other controls in the visual tree.
I had this problem and the fix posted by user572559 fixed my issue. For those that need it, below is what I did (modified for posting):
_scrollViewer = new ScrollViewer();
_scrollViewer.AddHandler(
ScrollViewer.MouseLeftButtonDownEvent,
new MouseButtonEventHandler(OnMouseLeftButtonDown),
true);
_scrollViewer.AddHandler(
ScrollViewer.MouseLeftButtonUpEvent,
new MouseButtonEventHandler(OnMouseLeftButtonUp),
true);
...
void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
...
}
void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
...
}
Also note that if you hare handling these you may be handling MouseMove as well. MouseMove worked for me without needing to do this, and it also does not seem to be supported in this fashion (not a bubbling event).
You can prevent e.Handled on MouseButtonEventArgs by overriding ScrollViewer like this
public sealed class ClickScrollViewer : ScrollViewer
{
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
this.Focus();
}
}
Related
I have a C# WPF application with a User Control displayed inside a ScrollViewer:
<ScrollViewer HorizontalScrollBarVisibility="Auto" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel" MouseWheel="ScrollViewer_MouseWheel">
<Drawing:DrawingWindow Name="Drawing" MouseWheel="Drawing_MouseWheel" PreviewMouseWheel="Drawing_PreviewMouseWheel"/>
</ScrollViewer>
I've tried putting an event-handler for all scroll-related events both on the contained element and the ScrollViewer itself. Each of the handlers is basically just this:
private void Drawing_MouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
}
private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
}
private void Drawing_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
}
private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
}
Even with all this, the vertical scroll-bar still responds to the mouse-wheel when I scroll on top of the Drawing element.
What am I doing wrong? I've seen a lot of posts where setting e.handled appears to be the solution:
Disable mouse wheel scrolling in scrollviewer
I am trying out custom routed events, but I get a TargetInvocationException when compiling with an Attached Event Handler.
I have the following code inside custom control EventRaiserControl:
public static readonly RoutedEvent KickedEvent = EventManager.RegisterRoutedEvent("KickedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(EventRaiserControl));
public event RoutedEventHandler Kicked
{
add
{ this.AddHandler(KickedEvent, value); }
remove
{ this.RemoveHandler(KickedEvent, value); }
}
private void btn1_Click(object sender, RoutedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(KickedEvent));
}
I then have the following XAML in my main window:
<StackPanel local:EventRaiserControl.Kicked="StackPanel_Kicked">
<local:EventRaiserControl Kicked="EventRaiserControl_Kicked"/>
</StackPanel>
With the following handlers in the MainWindow code behind:
private void StackPanel_Kicked(object sender, RoutedEventArgs e)
{
Console.WriteLine("Caught Kicked Event at Panel level.");
}
private void EventRaiserControl_Kicked(object sender, RoutedEventArgs e)
{
Console.WriteLine("Caught Kicked Event at Control level.");
}
My code works fine with this handler:
<local:EventRaiserControl Kicked="EventRaiserControl_Kicked"/>
But fails with TargetInvocationException the moment I add the attached handler:
<StackPanel local:EventRaiserControl.Kicked="StackPanel_Kicked">
Can somebody help? What am I missing / misusing?
Many thanks
At first I was surprised why it is, but I saw the reason after coding as your code. Just change
EventManager.RegisterRoutedEvent("KickedEvent"....
to
EventManager.RegisterRoutedEvent("Kicked"....
How I can show or hide a groupbox from xaml.cs. I try to do this in the checkbox's event:
private void cbDaily_Checked(object sender, RoutedEventArgs e)
{
gbCalendar.Visibility = Visibility.Visible;
}
But this don't work.
It must be work on checked/unchecked events of checkbox like this way :
private void chkTest_Checked(object sender, RoutedEventArgs e)
{
grpTest.Visibility = System.Windows.Visibility.Visible;
}
private void chkTest_Unchecked(object sender, RoutedEventArgs e)
{
grpTest.Visibility = System.Windows.Visibility.Hidden;
}
It is working fine in my sample application. Can you please give more details of your problem, so I can have better idea. Is event fired properly ? Make sure name of groupbox in code behind is correct or not ?
What is the equivalent Following code in wpf
code in winapp :
private void textBox1_Enter(object sender, EventArgs e)
{
MessageBox.Show("www.stackoverflow.com");
}
There is no Enter event on a WPF textbox - you could use the GotFocus event to the same effect though.
private void textbox1_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
MessageBox.Show("www.stackoverflow.com");
}
this is accessed in the XAML as follows:
<TextBox GotFocus="textbox1_GotFocus"/>
I need to be able to collapse expander on clicking anywhere outside the expander area. I am wondering what technique can be used. Any advice is highly appreciated.
Expander XAML - set binding to isExpanded:
<toolkit:Expander Header="Tasks" IsExpanded="{Binding IsExpanded}">
Code behind:
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (value == _isExpanded)
return;
_isExpanded = value;
OnPropertyChanged("IsExpanded");
}
}
I assume you are using code behind.
Can you please try this in the Expander's MouseLeave & MouseEnter handlers
private void expander1_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
Application.Current.RootVisual.MouseLeftButtonDown += RootVisual_MouseLeftButtonDown;
}
void RootVisual_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.expander1.IsExpanded = false;
}
private void expander1_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
{
Application.Current.RootVisual.MouseLeftButtonDown -= RootVisual_MouseLeftButtonDown;
}