C# Why use SuspendLayout()? - c#

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".

Related

How do I make controls extend passed a control bound or overlap with others?

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.

Programmatically filter custom properties

I have an existing custom control library with controls which may contain properties: HeaderStyle, ModalStyle, Collapsable, etc...
In the user interface the program is currently displaying a categorized list of these properties. I am trying to update this code to hide properties they dont normally use. I have a list of properties to hide/show based on button click but I am not sure how I can hide these fields programmatically.
I would like to retain any values entered into the fields before hiding and re-display the values if the fields are shown again.
Here is a property that current exists but would like to be hidden/shown on toggle.
/// <summary>ModalStyle property for control</summary>
[XmlAttribute]
[DefaultValue(Utility.Common.Enumerations.ModalStyle.None)]
[Category(PropertyCategories.Rendering)]
[Description("Modal dialog style")]
public ModalStyle? ModalStyle
{
get { return control.ModalStyleActive; }
set { control.ModalStyle = value; }
}
My original though was to do some variant on #if DEBUG but use my own Conditional however I was unable to find a way to change my conditionals via button/toggle.
Can anyone please help with a solution to my problem? I have 20-30 controls with 20 to 30 properties that would like to be filtered.
I have two suggestions that, while they may not give you the exact functionality desired, will keep your solution much more straight forward.
First:
Since you are the library developer you should just decide what properties you want other developers to have access to though the IDE properties window. If a property is seldom used or not very useful through the IDE then just place the [Browsable(false)] attribute on it.
Second:
If you really want all properties to be visible in the IDE properties window, but want to give individuals a way of hiding the more advanced (or less used) ones, just throw them all in an 'Advanced' category. The user can then simply collapse that category and forget about them.
Also: Take a look at Oliver's answer to this question:
[how-to-show-or-hide-properties-dynamically-in-the-propertygrid]
I'm not sure to understand what you are trying to achieve.
When you use Attributes, those are static to the class. So, in your case, when you toggle a show/hide on an object, it's on an instance of the object. Also, you cannot change an attribute value at run-time.
Maybe you should try an alternate solution like creating a global
map<pair<type of object, property name>, is shown>
and update that accordingly from your editor.
And if you want to use something like a property grid, you will have a problem since it won't check your map, but it can be fixed. You could create a new class at run-time and make it a proxy to your current instance. (check on the net how to achieve that, but it's quite simple. There are 2 possibilities: compile from a string or use the ILGenerator.
Hope this help.

WPF Binding and historical values

I'm currently writing a WPF progress bar that includes a rate (see Windows 8 - Fancy Progress Bars API?).
The screenshot below shows what I've got so far (left) and a badly done all in code as part of my learning exercise (right). I'm now trying to convert the code version to use as much XAML as possible.
I've got most of the way there by creating a new class called RateBase and implementing it in a similar way to RangeBase. I've then added a new instance and provided a template file RangeGraph. I'm attempting to do this as by the book as possible, but I'm not sure how to tackle the final stage.
I now wish to add a graph, this graph is to display the rate as it has changed historically as the progress has progressed. I have 'Rate' as a value I can bind to, but I believe somwhere I need a Double[] containing my historical rate values. My question is where should this be placed (I don't really want to pollute RateBase) and how do I bind to it from my template (I don't believe I can bind to RangeGraph.cs if I add properties on there or am I wrong?)
You are right, you will need historical Data. In my opinion, whenever the bound Dependency Property Rate changes, you should move the old value into an IEnumerable that's defined on the graph control itself (The same place that has the DP) and use that to draw the lines. I personally would create a class named MyControlData and add an instance of that to the control.
You might also want to add a Timer and move the current Rate to the IEnumerable when it Elapses, so longer streaks of the same rate will appear as multiple bars. Depends on how you actually determine progress. You might get into the following dilemma here : The Rate changes at a different interval than the Percentage in most cases - what floats your boat?
Keeping the history in your control's scope leaves your application agnostic to the history of your Rate, but lets your control display it as required.
To use DataBinding in a UserControl, edit the <UserControl x:Name="myControl"> node in Control.xaml and add a name like shown here. Wherever you want to bind, refer to ElementName=myControl. Please note that you will have to implement INotifyPropertyChanged on the Control (or on MyControlData) if you want to achieve this - or, and that would be advisable, directly implement it as a dependency property.
And BTW, if you have no idea how to achieve what you intend to have a look into ItemsControl. I think what you want to do can easily be achieved by means as simple as using ItemsControl and ItemsTemplate, where the ItemsSource is your historical data and the ItemTemplate depicts your current rate in comparison to your MaxRate. MaxRate is another property you can set from the DependencyProperty Rate's changed handler.

How to prevent Design View from using default constructor?

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.

Delay drawing of a WindowsFormsHost?

Is there a way to delay the drawing of a WindowsFormsHost? It's hosted in WPF.
It hosts a COM object which is an ESRI ArcEngine AxTocControl. Visually it looks like a table of contents tab.
I'm removing a number of objects from the table of contents and adding a different objects in a single function.
When I remove an object, the TOC control blinks and removes and object, then I add an object, and it blinks and adds an object. Since I am adding and removing 20 objects, its blinking 20 times. I would like to delay the drawing -- do all my operations -- and then resume drawing -- hopefully i will only have 1 or two blinks / flashes.
So to summarize, is there a function or technique (I don't care how hacky it is) to delay the drawing of a WindowsFormHost - let some things execute - and then resume drawing?
Well, you can create your own WindowsFormsHost subclass for this specific scenario and override WndProc. From there, you can decide to silently ignore (by not calling base.WndProc) all drawing-related messages as long as a "suppress updates" condition holds.
The condition you can implement any way you like, e.g. set up a public PausePainting() / ResumePainting() method in your class that sets a boolean field.
You will also have to remember to repaint when e.g. ResumePainting() is called, because you don't want your control to never update.
In the end it's not going to be as simple as A-B-C, but the concept is sound so it should work out.
You can use Thread.Sleep(0) to introduce a delay.
You could try processing everything, adding them one by one to a list, then add the whole list at one time.
myWpfControl.Clear();
List<EsriModel> items = new List<EsriModel>();
// Code to populate your items
myWpfControl.AddRange(items.ToArray());
Could it be that simple? That should prevent your WPF Control from flickering as you add them one by one.

Categories

Resources