I have some basic override code in the same class to catch mouse events. I can get OnMouseWheel to fire, but other click events do to not fire with the same code.
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
Debug.WriteLine("mouse down"); //does not work
}
protected override void OnMouseWheel(System.Windows.Forms.MouseEventArgs e)
{
Debug.WriteLine("mouse wheel"); //works
}
Does OnMouseWheel need focus to fire? That has been what I have been trying to troubleshoot so far.
protected override void OnMouseClick ( MouseEventArgs e )
{
Debug.WriteLine("Mouse click"); //works
}
private void panel1_MouseClick ( object sender, MouseEventArgs e )
{
OnMouseClick(e);
}
In your actual design window make sure you attached the event to the Control. If you need to do it programatically, then
this.panel1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseClick);
Note:
Yes I know the control names aren't the exact same and you aren't using MetroControls, but it's the same idea.
You need to call the base method implementation of OnMouse events so the base class can react to the events:
protected override void OnMouseDown(MouseEventArgs e)
{
Debug.WriteLine("OnMouseDown");
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
Debug.WriteLine("OnMouseUp");
base.OnMouseUp(e);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
Debug.WriteLine("OnMouseWheel");
base.OnMouseWheel(e);
}
Related
I have a custom control derived from control. The mouse events, such as OnMouseLeftButtonDown (MouseButtonEventArgs e), can be used without any problems. Now I would like a combination of e.g. left-ctrl and left mouse click. But I just can't manage to respond to keyboard events in my "custom control".
Can someone give me a hint how to implement this?
This overriden method works fine.
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
if (isKeyCtrlDown)
{
Debug.WriteLine("Test");
}
}
And this overriden methods will not fired.
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.LeftCtrl)
{
isKeyCtrlDown = true;
}
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
if (Keyboard.IsKeyUp(Key.LeftCtrl))
{
isKeyCtrlDown = false;
}
}
Thanks for any help.
I'm new to WPF, and trying to fix a bug with a draggable window.
I'm checking a bug in an app I maintain where we have a Behavior class, with which we implement a dragging mechanism.
When I go to windows' display settings and change the scaling (100%/125%/150%/175%), windows seems to dispose the app's window and recreate it.
This is where the AssociatedObject member of the behavior class becomes null, so when the Loaded event is invoked again, I have no AssociatedObject to work with.
How can I get the new AssociatedObject?
It seems like expected behavior since the UI element was recreated, but the behavior class is still 'alive' but can't do any work since it isn't familiar with the new UI element (If I understand things correctly, as I mentioned, I'm new to WPF)
Thanks!
Edit: adding a sample class
public class SetWindowSizeBehavior : Behavior<FrameworkElement>
{
protected override void OnDetaching()
{
Console.WriteLine("detaching");
base.OnDetaching();
}
protected override void OnAttached()
{
AssociatedObject.Unloaded += AssociatedObject_Unloaded;
AssociatedObject.Loaded += AssociatedObject_Loaded;
base.OnAttached();
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
Console.WriteLine("");
var a = AssociatedObject;
}
private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
{
Detach();
}
}
After I'm changing the scaling settings at the windows display settings menu, this is the call stack:
AssociatedObject_Unloaded
OnDetaching
AssociatedObject_Loaded <- this is where AssociatedObject becomes null
I hope the question is more clear now, and if not, would love to get some comments about missing info...
Can you try overriding the 'OnPropertyChanged' method
public class SetWindowSizeBehavior : Behavior<FrameworkElement>
{
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (AssociatedObject == null)
{
// so, let'save the value and then reuse it when OnAttached() called
_value = e.NewValue as string;
return;
}
if (e.Property == PasswordProperty)
{
if (!_skipUpdate)
{
_skipUpdate = true;
AssociatedObject.Password = e.NewValue as string;
_skipUpdate = false;
}
}
}
protected override void OnDetaching()
{
Console.WriteLine("detaching");
base.OnDetaching();
}
protected override void OnAttached()
{
AssociatedObject.Unloaded += AssociatedObject_Unloaded;
AssociatedObject.Loaded += AssociatedObject_Loaded;
base.OnAttached();
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
Console.WriteLine("");
var a = AssociatedObject;
}
private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
{
Detach();
}
}
From here:
https://stackoverflow.com/a/42312799/7779827
Eventually I used #DanielFr's idea and when I detected that the associatedObject is null (cause the base class Behavior sets it to null when the detach method is called) I used the sender object and:
if (AssociatedObject == null)
{
//If we got here then we didn't go through onAttached in this iteration
Attach((FrameworkElement)sender);
}
When FrameworkElement is my T in my Behavior class
I have two controls.
class ControlA
{
public ControlA()
{
//some code
this.PreviewKeyDown += ControlA_PreviewKeyDown;
}
protected void ControlA_PreviewKeyDown(object sender, KeyEventArgs e)
{
// do A things
}
}
I also have a control B which inherits control A
class ControlB : ControlA
{
public ControlB()
{
//some code
this.PreviewKeyDown += ControlB_PreviewKeyDown;
}
protected void ControlB_PreviewKeyDown(object sender, KeyEventArgs e)
{
// do B things
}
}
when the PreviewKeyDown event is fired, both ControlB_ and ControlA_PreviewKeyDown are fired. But I want only ControlB_PreviewKeyDown is fired for a ControlB. Is that possible? If so, how to implement that?
Thank you so much.
Assuming you can change the code of both ControlA and ControlB here's a possible solution:
class ControlA
{
public ControlA(bool subscribe = true)
{
if (subscribe)
{
this.PreviewKeyDown += ControlA_PreviewKeyDown;
}
}
protected void ControlA_PreviewKeyDown(object sender, KeyEventArgs e)
{
// do A things
}
}
class ControlB : ControlA
{
public ControlB() : base(false)
{
//some code
this.PreviewKeyDown += ControlB_PreviewKeyDown;
}
protected void ControlB_PreviewKeyDown(object sender, KeyEventArgs e)
{
// do B things
}
}
your "problem" is due to the fact that ControlB class constructor calls also the ControlA constructor... you can create a ControlA(bool fromParent=true) which doesn't add the handler of this.PreviewKeyDown += ControlA_PreviewKeyDown;
HTH
Try setting e.Handled = true; in the ControlB handler, and in the ControlA handler, wrap the logic in an if(!e.Handled)
Or, since you have the ControlA handler as protected, you can unsubscribe from it in ControlB constructor:
this.PreviewKeyDown += ControlB_PreviewKeyDown;
In PreviewKeyDown we will check for sender type to determine from which control event fired.
Like
protected void ControlA_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (sender.GetType() == typeof(ControlA))
{
// do A things
}
}
protected void ControlB_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (sender.GetType() == typeof(ControlB))
{
// do A things
}
}
I've created a custom user control for a windows form that will operate similar to a button (and please don't suggest that I just use a button, because I will be storing data in this user control), but I can't figure out how to get the OnClick() event to fire. I've sifted through a handful of tutorials and looked at a few similar questions on the site, but I can't seem to get the event to fire off - so I'm either doing something wrong or everyone posted incorrect code (I hope it isn't the latter)
In my custom control.cs,
namespace MobCreator {
public partial class MOBSample : UserControl {
public MOBSample() {
InitializeComponent();
}
protected override void OnMouseUp(MouseEventArgs e) {
this.BorderStyle = BorderStyle.FixedSingle;
base.OnMouseUp(e);
}
protected override void OnMouseDown(MouseEventArgs e) {
this.BorderStyle = BorderStyle.Fixed3D;
base.OnMouseDown(e);
}
public event EventHandler ButtonClick;
private void OnButtonClick(object sender, EventArgs e) {
// invoke UserControl event here
if (this.ButtonClick != null) this.OnButtonClick(sender, e);
}
}
}
And in my form.cs,
private void MobCreatorForm_Load(object sender, EventArgs e) {
UserControl1.ButtonClick += new EventHandler(this.CustomEvent_Handler);
}
private void CustomEvent_Handler(object sender, EventArgs e) {
Console.WriteLine("Click");
}
However, when I run the program my console never outputs "Click".
Check this link on MSDN: it is a simple Event tutorial, you should be able to adapt it to your scenario.
At a first look, what you are probably missing is a Delegate for your event.
Try this
private void MobCreatorForm_Load(object sender, EventArgs e)
{
CustomEvent_Handler(null,null);
}
private void CustomEvent_Handler(object sender, EventArgs e)
{
Console.WriteLine("Click");
}
I have contentpage overriding the OnInit event of a masterpage. The override works fine, until I put a custom user control on the page: in this case the OnInit event does not fire for the contentpage (no overrides are used in the user control)
What are the possible causes/solutions for this? (I use the OnInit event to create dynamic controls)
Edit:
now i tried this in the content page:
(The OnPreInit part runs, but Masters_Init does not get called...)
protected override void OnPreInit(EventArgs e)
{
base.Master.Init += new EventHandler(Masters_Init);
}
void Masters_Init(object sender, EventArgs e)
{
//code
}
Are you calling the base.OnInit?
public override void OnInit(EventArgs e)
{
// code before base oninit
base.OnInit(e);
// code after base oninit
}
Update
public class Page1 : Page
{
public Page1 : base() {
PreInit += Page_PreInit;
}
void Page_PreInit(object sender, EventArgs e)
{
Master.Init += Master_Init;
}
void Master_Init(object sender, EventArgs e)
{
//code
}
}
Also as mentioned in the comments I would recommend not overriding the events if you don't have to, but if you must be sure to call the base. so in your edit above it should be
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
base.Master.Init += new EventHandler(Masters_Init);
}