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.
Related
I have a wpf grid setup where I have two custom buttons that are next to each other. First picture is how the design window looks like, however, functionally, it looks like the second picture. I want them to function like the grid doesn't block them (closely resembling the first picture.)
The current xml I have is based on this MSDM which is very basic.
I do not know how to proceed. Do I have to use a different control panel/container or is there a setting to allowed them to extend passed the grid if the other button isn't above it (like zpanel?)
E: I couldn't find any other questions for this, so please link to any searches/posts with information on it.
Turns out I can use canvas and just do a bit more xml to keep the design the same. I would still like to know if it is possible to overlap them in any way for future use.
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.
I am reading up about SuspendLayout() and ResumeLayout(). What I can't figure out is, why should I do/use this. I know you use it when you add controls at runtime to a control-container.
It has something to do with setting properties like Dock, Anchor, Location, etc.
But I don't understand what the additional value is of Suspend- and ResumeLayout(). What does these methods take care for?
Basically it's if you want to adjust multiple layout-related properties - or add multiple children - but avoid the layout system repeatedly reacting to your changes. You want it to only perform the layout at the very end, when everything's "ready".
I have a somewhat complex UserControl, and Visual Studio 2008 is giving me a rather harmless annoyance when working with it. Every single time I open the control with the Designer, it decides to immediately change some of the harmless values set by the designer - namely the initialization of Size properties. If I save those changes, close, and reopen, it almost invariably ends up deciding another component of my control needs its initial size changed, ad infinitum. Luckily these changes are harmless since I'm using automatic sizing everywhere, but this is quite annoying to work with. I haven't the foggiest on where to start figuring out what's going wrong, my only thought right now is that the Designer is assigning the results of auto-sizing back into the initial size fields every time I open the control. Any ideas on causes/fixes?
Edit: Also, I am using Application Settings to save sizes of certain resizable child components across runs of the application, but I really hope the Designer is smart enough to understand that it should only ever be using the defaults.
Maybe it can help:
I noticed that FormDesigner (no WPF, no Web etc) has a strange behaviour if you insert one custom UserControl.
There is a random change of other controls (GroupBox, EditBox, ComboBox) size (to me happened with width).
The controls choosen to resize seems to be random, but across restarting of vs2010 it is always the same. If deleted and reinserted, the designer chooses a different control do randomly resize...
I changed the property AutoScaleMode of my UserControl from "Font" to "Inherit" and it did not happen again.
You're right, the designer often tries to add default values to properties.
Add this on top of the property declaration:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
That will tell the designer to ignore this property.
I have somewhat similar problem. I am using Infragistics GroupBox on a user control which I inherited and now want to change its look and feel in the derived class. I have made it protected in base class -- so it does allow me changing properties in derived class. But it does not save it. Every time I open it -- I get same old values of base class back.
Any idea?
Edit: I figured it out.
Trying various value for one of the above given answers.
Using [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] instead of [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] generates code for changed properties - and things work as desired.
Try overriding the DefaultSize property of your control.
From MSDN:
The DefaultSize property represents the Size of the control when it is initially created.
When designing WPF application UI's in XAML, should every container-type control contain a layout control to house all children controls?
Take a group box, for instance. I can either throw controls onto the group box directly, or I can use a layout control and place the layout control inside of the group box and then controls in that.
I can see the benefit in the latter because the layout control represents a set of well-defined rules for how the children will behave. In doing this, however, my XAML tree starts getting deeply nested and a little harder to navigate.
Given this, is it best practice to always use layout controls or are there cases where it is perfectly acceptable to throw a control inside group boxes and tab items without such? What would be the negative implications of this if any?
There is no negative implications in using Layout panels because even if you havent specify one, there is a default one in the VisualTree. If you don't use one explicitly, your XAML may looks cleaner.
Most of the ItemsControls have a StackPanel as the default Layout. So it is basically a question of whether you want a StackPanel behavior to arrange your child items or not?
Jobi is correct that there are really no implications either way, but my gut instinct has always been to use a Container to hold multiple controls. A lot of that is driven by my need for highly structured organization, but mostly it just makes sense to me.
I do end up with a lot of nested Grids, StackPanels, etc. Yes, the tree can get pretty deep, but I use Blend almost exclusively for layout and design, so navigating the tree is not so bad, especially if you remember to give everything good descriptive names.
I don't know if it's "Best Practice" but it certainly works best for me.