Instead of using all the base wpf controls such as Label, TextBox, Grid, ect. I want to create a sub class of all these base controls and use the sub class.
e.g.
public class MyTextBox : TextBox {}
They would be dummy classes for now, but it leaves room to be expandable in-case I need to in the future. Is this recommended or is it unnecessary?
This is a text-book definition of yagni
It sounds unnecessary, unproductive, and definitely not recommended!
If for some reason you need a subclass in the future it will be much easier to simply create it then than it to do lots of unnecessary work now.
This sort of approach tends to be overkill. Where it does have its uses is when you know you will need to change the base UI controls at some point in the future. So if you were using a third party control suite then you might look at this approach, but you wouldn't want to do it with the MS controls as they are baked into the framework - you aren't going to change those!
Another approach is to ensure you follow a pattern like MVVM - this ensures that you have a UI that is nicely separated from your working code, and you can change controls with the minimum impact.
I think this is unnecessary. We can easily override the look and feel of a control using styles. In case you want to add properties, you can use attached properties.
Related
Apologies if I'm grossly overlooking something here, but I'm a bit stumped:
I'm developing a set of custom controls which all should share some common DependencyProperties. Say DPropA and DPropB. I want to avoid to copy/paste the same DPs over multiple controls, however, since they are custom controls, they all already inherit from their respective base control (Button, TextBox etc.) and MI is not possible. DP are static fields, so I can't put them in an Interface either.
Also, I later may need to access some of these properties via reflection. This isn't an issue with properties that are near the top of the hierarchy (e.g. Control.FontStyleProperty), but since I can't declare a base class with my DPs this is also a problem.
How can I solve this? I'm a bit suprised I barely found something about that problem, since I thought that sharing a common set of DPs for custom controls isn't actually an uncommon problem.
This is a bit hard to explain in the title, but here's my situation. I have existing code and use the standard Textbox throughout. I have decided that I need to add functionality to the Textbox class so I created MyTextbox derived from Textbox and added what I needed. Now I want to permanently use MyTextbox instead of Textbox. I Should be able to force all instances of Textbox (present and future) to use MyTextbox.
I have done something similar before in C++ along the tune of
typedef Textbox MyTextbox;
If this makes sense, is it possible to do in C#?
Why not do a mass find/replace across your solution? This can be done quite easily in Visual Studio.
You could do the following at the top of each file that uses a Textbox:
using Textbox = Custom.Namespace.MyTextbox;
I don't recommend this because anyone seeing what looks like the standard text box in your code may not realize it is in fact your own custom text box. This may also cause ambiguity when compiling the related code.
Another way to make sure that your new functionality is available to everyone who uses TextBox instead of MyTextBox is to use extension methods. Then you wouldn't have to worry about the user using the wrong class.
MSDN Article on Extension Methods: http://msdn.microsoft.com/en-us/library/bb383977.aspx
Why would you need to refer TextBox class again if you already have created MyTextBox. Remember, MyTextBox has all the functionality from TextBox and its own functionality as well.
In case you want to change all existing textboxes from your to comply to MyTextBox, you have to go manual. Edit them all because even if you change the type from .Net Framweork Base Class Library, exceptions would be thrown wherever a TextBox is called
Situation: I am making a Collapsible Panel. In my business situation, I am required to have the panel support the following:
A "direction" (ie, will it dock top, bottom, left, or right). This changes which direction it collapses and a few other things.
A "style". There are some predefined visual styles for this product (defining background color, gradient or not, text color, hover color, etc).
Here's the problem: certain styles are incompatible with certain directions. Here are the requirements:
There needs to be some way to prevent/warn the programmer if he/she coded the panel to have incompatible style and direction. For example, having the panel throw a runtime exception if they are incompatible will satisfy this requirement.
Not allow anyone to dynamically change either style or direction during runtime. If I need to, then I can allow it to be "dynamically" changed in InitializeComponent, but not anywhere else.
The panel needs to be visible in Design View. but not necessarily able to be dragged and dropped in design view, and technically I don't need to even alter the attributes of the panel in design view. Though I obviously want either of those other things if possible.
One potential solution: Have the constructor take two inputs: a direction and a style. That way both the changes are treated as an atomic action. If they are not both changed at the same time, then between changing the direction/style and then changing the other, the panel will be in an inconsistent state. I want to avoid that.
How can I get the Design View to not use the default constructor and/or what are better practices for fulfilling the requirements?
Note
The Panel is only an example and a use case to ask the broader question. I want this post to answer the direct question on the best practices for getting the Design View to handle my requirements. If the Visual Studio supports injecting a non-default constructor in InitializeComponent, then I want to know how (and any caveats with that). If there are better practices which fulfill the listed requirements, then I would like to know that as well.
Add support for the ISupportInitialize interface which the designer can use to set all the properties and tell you when it's finsihed.
Partial answer: you can't make Designer use some custom constructor. You will need to put the logic in property setters.
Throwing exceptions there might lead to messy Designer errors. How about resetting fields to some proper state instead?
You will probably need to differentiate the behavior depending if you're in DesignMode. If you haven't already, take a look at DesignMode considerations.
In my project I have a settings form. Where if any changes happen I have to notify user about it if he wants to leave that page without saving his changes. At this time I am doing this by catching every control change event. I am sure there is a better way - like catching the change event from its container. Is it possible?
Rather than worrying about the controls directly, how about creating a Settings class that implements interfaces from System.ComponentModel like INotifyPropertyChanged and IDataErrorInfo and use data binding to get the values in and out of the controls.
Your Settings class can then not only record whether anything has changed but also make validation of the user input easier.
A good place to start is MSDN.
You have the right solution, but you may want to be very generic about catching the change events. For example, you could try something like this right after the InitializeComponent(); line in the constructor:
foreach(Control c in Controls) {
c.TextChanged += new EventHandler(genericTextBox_TextChanged);
}
genericTextBox_TextChanged would set a form-wide hasChanged flag to true, or something really basic like that. You may need to make this into a recursive function that loops through all of the children of c if it has child controls.
Let me offer you some kind of a workaround. My offer is to create a custom DataSet. Then add tables corresponding to the form controls. After this you can bind each form control to this dataset.Pros: You keep all the controls data-bound. So you don't need to care about the changing of particular control. You have just to control dataset changes. Cons (maybe): after this you should rewrite settings preview mechanism. Instead of changing controls you have to change data. IMO, it's not so hard, but I have no idea about this approach in your applicationI think this approach will be, at least, easy to debug.
If it's web, look at the unload event for javascript
I'm making a custom control.
Basically what I'm looking for is a OnPreInit event in custom controls. I basically need to know that all of the controls that will be loaded of type MyCustomControl are constructed or not.
Ok, so basically I need to know in the constructor if the current instance being constructed will be the last.
Note: My custom control contains other controls(though this isn't guaranteed) but it will not contain controls of MyCustomControl class.
I've thought about doing an override of AddParsedObject. But if the instance of my custom control doesn't contain any controls, will this still get called?
Unfortunately the approach you're describing is "non-trivial". That means it might not be technically impossible, but so difficult to do correctly and has so many negatives/downsides that you will be better off stepping back and analyzing the larger problem for a different design. Perhaps if you re-posted articulating the end goal you're trying to accomplish, we can help you find an approach that is viable.
I hate to say use a counter, but you're either going to have to pass state information through a dedicated class (or the context,) which you could do in the constructor of the control prior to testing if you've got as many as you need, or you could do a recursive walk through Page.Controls and their .Controls and test each one for type....