I created an Extension for the DataGrid. I would like to know what is the better way to do thing in event.
Is it better to add an Handler like this :
class MyDataGrid : DataGrid {
public MyDataGrid() {
this.PreviewKeyDown+= MyDataGrid_PreviewKeyDown;
}
protected void MyDataGrid_PreviewKeyDown(/* args */) {/* do stuff */}
}
or with override like this:
class MyDataGrid : DataGrid {
public MyDataGrid() { }
protected override void OnPreviewKeyDown(/* args */) {/* do stuff */}
}
And if I let base.OnPreviewKeyDown(e); in the override, does it do the same as the eventHandler?
It probably does not matter either way. That said, you should override the method -- its whole purpose is to handle the event from within the control. If you add an event handler, then you are needlessly adding another method to the event's invocation list (ie, slight performance hit).
If you want to be strict/fanatical about performance, then you could also make your "MyDataGrid" class "sealed".
sealed class MyDataGrid : DataGrid { ... }
That allows compiler/runtime to determine that it doesn't need to check for any overrides of the virtual method "OnPreviewKeyDown" above your "MyDataGrid" class.
Related
I have a data structure organised as such:
A List<Graphic> containing a List<Symbol> which contains a List<Alias> amongst other things.
I want to be able to run a function within the Graphic class whenever anything changes within an alias/symbol/graphic. The best way that I can see to do this would be to implement IPropertyChanged on each of the three classes. However, is it possible to cascade these whilst getting a reference to the Graphic as to what exactly changed?
Note: The changes will generally be to the properties within an Alias but it is just as plausible that a Symbol could be removed/added or renamed.
You can leverage class ObservableCollection<T> that implements INotifyCollectionChanged and INotifyPropertyChanged
Basically, you need to create a derived class and override some methods
public class Data
{
public ObservableCollection<String> InnerCollection { get; set; }
}
public class collection : ObservableCollection<Data>
{
protected override void InsertItem(int index, Data item)
{
item.InnerCollection.CollectionChanged += InnerCollection_CollectionChanged;
base.InsertItem(index, item);
}
private void InnerCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//Actually it does not make any sense. You may need to construct something special. But firing an event it would be enough
OnCollectionChanged(e);
}
protected override void RemoveItem(int index)
{
var date = base.Items[index];
date.InnerCollection.CollectionChanged -= InnerCollection_CollectionChanged;
base.RemoveItem(index);
}
}
Using something like this, you can nest your events as deep as you want.
I want to ask this question because of some safety mechanism for my code.
This may seem like useless, but it already made me lose much time debugging.
public class AnimalClass
{
virtual void Mod{}
virtual void UpdateSomeValues{}
}
public class CatClass : AnimalClass
{
override void Mod{}
override void UpdateSomeValues{}
}
Is there a way in C# to automatically fire up Cat's UpdateSomeValues function whenever Cat's Mod function is called (without having to call it manually from Cat's Mod function)?
And if possible, make it the same for all derived classes?
No. You could solve that issue by introducing another, protected method that derived classes can override, and make the public one call into it once all the necessary processing is done:
public class AnimalClass
{
public void Mod()
{
// do stuff
ModImpl();
}
protected virtual ModImpl() {}
}
With that derived classes would implement ModImpl() if they want to do some extra processing, and you're sure that // do stuff still happens when Mod is called.
In my project, I want to override Touchup Event Handler which is build in the WPF. I do not know how to override this event handler for my own use. Is that possible? Someone could give some examples, I do not get some references or example about it.
You can create a custom control and override the events. refer the below code i tried for TextBox control.
class TextBoxEx : TextBox
{
protected override void OnTouchUp(System.Windows.Input.TouchEventArgs e)
{
base.OnTouchUp(e);
}
protected override void OnTouchDown(System.Windows.Input.TouchEventArgs e)
{
base.OnTouchDown(e);
}
}
It is possible.
Let's say you want to override this TouchUp event (Completely override it). You will need to define a new function to handle this. Something like :
private void Custom_TouchUp(object sender, TouchEventArgs e)
{
// Do some stuff there
}
(It may not be TouchEventArgs, I haven't tried it, but it looks like it)
Then, in your xaml, in your object definition, you need to specify to the targeted object that it should use this function. If it's a combobox (for example), you'll have something like this :
<Combobox [...] TouchUp=Custom_TouchUp>
<Eventual parameters>
</Combobox>
And voila! Your object will use your new function.
Now, let's say you just want to alter a tiny bit the current event, then you can just override the OnTouchUp function that will be called when the event occurs. Something like this should do :
public override void OnTouchUp()
{
base.OnTouchUp();
// Other stuffs
}
But then, every element of the same class will act the same. So that's really useful when you want to define a new custom class
I am creating an class library in C++/CLI to be used with C#, and as part of that library, i am offering up a customised version of System.Windows.Forms.Form and System.Windows.Forms.Control as System.Windows.Forms.HAForm and System.Windows.Forms.HAControl. I want to override OnPaint in a way that allows me to have OnPaint_Pre, OnPaint_Post AND OnPaint as i need to handle certain things every time before any painting is done, and handle some things AFTER painted has completed.
While this alone is simple enough, with this being a class in a library that is to be inherited from, i do not want to simply create an OnPaint in my class as this will be overwritten by the end developers OnPaint, and even if they do call base.OnPaint, the events will be fired out of order. i.e. OnPaint_Pre, my OnPaint, OnPaint_Post, sub classes OnPaint.
How would i create a class that inserts two events, one before the existing event, and one after?
I hope you don't mind me using C# syntax instead of C++/CLI...
You can make the HAForm/HAControl OnPaint override sealed, and create a new virtual function that derived classes can override. You can even use an intermediate class to give the new virtual function the same name:
public class HAControlBase : Control
{
protected virtual void OnPaintPre(PaintEventArgs e) { }
protected virtual void OnPaintPost(PaintEventArgs e) { }
internal virtual void OnPaintImpl(PaintEventArgs e) {
base.OnPaint(e);
}
protected sealed override OnPaint(PaintEventArgs e) {
OnPaintPre(e);
OnPaintImpl(e);
OnPaintPost(e);
}
}
public class HAControl : HAControlBase
{
internal sealed override void OnPaintImpl(PaintEventArgs e) {
OnPaint(e);
}
protected new virtual void OnPaint(PaintEventArgs e) {
base.OnPaintImpl(e);
}
}
Now, even if a derived class overrides HAControl.OnPaint, it will only be called after HAControlBase.OnPaint has already finished with OnPaintPre, there is no way to override Control.OnPaint (because that override is sealed) to call anything before OnPaintPre.
I wonder under what circumstances you would choose the first or the second design :
First design : the child method have to call the base method
public abstract class Base
{
public virtual void Enable() { IsEnable = true; }
public virtual void Disable() { IsEnable = false; }
public bool IsEnable { get; private set; }
}
public class Child : Base
{
public override void Enable() { /* do stuffs */ base.Enable(); }
public override void Disable() { /* do stuffs */ base.Disable(); }
}
Second design : a virtual method is used to be sure the child do not forget to call the base
public abstract class Base
{
public void Enable()
{
IsEnable = true;
OnEnable();
}
public void Disable()
{
IsEnable = false;
OnDisable();
}
public bool IsEnable { get; private set; }
public virtual void OnEnable() {}
public virtual void OnDisable() {}
}
public class Child : Base
{
override void OnEnable() { /* do stuffs */ }
override void OnDisable() { /* do stuffs */ }
}
Thanks
It depends if you really want to make sure IsEnable gets set or not. If you can imagine scenarios in which the user doesn't want to set it, then I suppose you leave it up to them to call the base method. Otherwise, do it for them.
The second, template-based approach is better in my opinion. It allows you to ensure that some base functionality is always called, and gives you room to add some if none is present at first without the risk of breaking any subclass.
As soon as you make a method virtual, you are giving a derived class a chance to break your class. A responsible deriver will always ask himself "should I call the base implementation?" Guidance for this should always come from documentation. MSDN uses standard verbiage:
Notes to Inheritors:
When overriding Xxxxx in a derived
class, be sure to call the base
class's Xxxx method so that blablah
happens.
The C# language makes that easy with the "base" keyword. Working from the assumption that this documentation is not available or unclear, your second example would strongly discourage a deriver to call the other base class method. After all, s/he wouldn't use the standard pattern. Use this pattern only if you want to discourage the inheritor from calling a base class method.
In the first one, where the overring class could prevent Enable from being set, I reckon Enable and Disable could potentially be misleading method names.
Something like TryEnable and TryDisable would probably be more accurate implying that there are situations where you cannot enable.
A third possible situation could be catered for if you took example 2 and changed it so the base class calls OnEnable before setting the flag:
public void Enable()
{
OnEnable(); // Exceptions raised from here prevent the flag being set.
IsEnable = true;
}
Then overriding classes could prevent the setting of the flag by raising an exception if an error were to occur. Thus error situations would prevent the flag from being changed.
Just food for thought.