What I need can probably be described as "reverse-anchor", "reverse-dock" or something like that (I have chosen to mention this just because "reverse-anchor" happened to be the first thing to come into my mind as a keyword candidate when searching for questions and answers that might already have been submitted discussing this subject, perhaps this will help people thinking a similar way to find this one in future). WinForms controls implement the Anchor property to set up adaptive resizing on containing control/form size change but I need the opposite - the form to resize adaptively to the controls.
A thing adding a minor bit of complexity to the task is that the controls meant to be added/removed/shown/hidden/enabled/disabled (and resized perhaps - this functionality is not really needed directly so far but I suspect it can turn to be required for compatibility with non-default Windows visual styles and themes that have potential to affect controls sizes unpredictably and can change at any moment of the app running) are not going to be the last ones on the form - a row of buttons will always be in between of the last control of the volatile group and the window lower border.
The actual task is to design a form that will display a collection of objects with a row of controls (a label, a text box and 0-2 buttons) corresponding each of them and it is strongly preferable to use just the very basic "common controls" avoiding grids, lists and stuff like that in this case (wrapping them in an additional container controls like panels is perfectly acceptable though, abstracting them in a separate "user control" can be considered too if this can really make the solution easier, more reliable or otherwise better, using hand-written code manipulating controls and form sizes is perfectly acceptable too (I can hardly expect a "set a magic property and it's done" kind of solution to exist for this task) but I haven't found a reliable algorithm so far (when to change what properties and what formulae to calculate new values with)).
The maximum capacity can be safely limited to something near 10 (or 20, perhaps, but not more - more would be just absolutely unreasonable to display on one form (provided scrolling is not an option)) so both ways are acceptable: to add/remove the controls in runtime or to put them on the form in the designer and just manipulate Visible and/or Enabled properties in the code. By the way I have found a problem with Visible - it gets switched off and back on by the framework internals before the form is rendered and other controls Anchor properties come in the game but I don't think it's a good idea to rely on this to happen always and the same way so just adjusting the form Size property on a control Visible property change does not feel really convenient).
What might be some good ideas relevant to implementing this behaviour?
PS: As far as I know this is a natural feature of WPF but I am to use WinForms to make the app runnable on Macs and, perhaps, other non-Windows platforms with help of Mono.
I'll tell you about some clues may help you:
1- correct to build your own Procedure for manipulating all the matter.
2- i advice to use a Wizard methodology (Next / Back buttons) so if the plate form is small like tablet or smart phone, so the mentioned procedure will decide how many Controls combinations (Label, text box, option button...) will be in each frame of that wizard and keep the remaining for Next button.
3- By the way if you will hide some controls use the original event fires to run the mentioned Procedure. (like a basic button to start the form so don't depend on visible / resize events).
4- Resize the size of each form of the wizard in the last part of the mentioned procedure.
If still a problem exists tell me and i hope i can help :-)
Reading lots of characters and updating a textbox was suggested to me when I created this question, and it was exactly what I was looking for (couldn't find it by just searching). However a couple of points need clarifying.
I am looking to upgrade to a ListBox or even RichTextBox. For now I want to be able to replace as little of the onscreen (and off, as an added bonus) text as possible.
In the first link Guffa wrote:
If the data is line based, use a list instead of a text box, so that you only have to update the last line when you add a character.
I have a split pane where updates to one TextBox are translated and shown on the other side, and vice-versa. I've briefly toyed with a ListBox but it doesn't provide the intrinsic text-editing funcionality of a TextBox so I went back.
What component should I be using? I wouldn't have thought that with all of .NET available I should have to consider Win32.
Ok, no one else has offered an answer so I will propose a solution which is the last one open to me short of refactoring back to Win32 API calls.
The solution is to use two textboxes. Instead of replacing the text element of the on-screen one you replace that of its dupe, which at the time is hidden, you then toggle the visible flags of both.
I'll let you know how it goes but it is major work for not much advantage, I'll prolly just live with a bit of flicker for now.
I have a WPF application, and it's slow.
It is NOT the rendering. Firstly, the rendering is quite simple, and secondly, I looked at it with WPF Performance Toolkit - nothing.
It is NOT in my own code. Firstly, the unit tests work fast, and secondly, if I replace all DataTemplates with blank ones, everything works fast.
So far, it looks like the slow part is template instantiation. That is, when you start the application, and open some complicated screen, it takes a lot of time. And by "a lot" I mean "a lot". Sometimes can be as much as 3-5 seconds - for example, when there's a datagrid with 100 rows. But when you go to another tab, and then go back to that same screen, it opens fast (as long as its viewmodel stays put).
This is very annoying not just because it's slow, but because I can't do anything about it. If I had some control over the slowness, I could, maybe, display some "opening, please wait" message or something...
Besides, when I look at some other WPF applications (most notably, ILSpy), they seem to work reasonably fast, despite the large amounts of data. This makes me believe that I'm probably doing something wrong. But I have no idea where to start.
Any ideas? Any classic mistakes? Any tips?
My exerience comes from working on the WPF mind mapping application NovaMind
A couple of months ago we completely rewrote our intermediate layer to solve the performance issues we had experienced. In a nutshell, creating our user controls seemed to be way to slow. Unfortunately I couldn't find a great way to profile the performance as neither the WPF Performance Suite nor commercial applications such as ANTS Profiler give you any detailed information on this part of the WPF process. (I asked this question back then)
We resorted to manually test our application by trial and error and removed parts of our user controls to see what exactly is the culprit.
In the end we solved the performance issues by completely rewriting our controls. We also cut down on the complexity of our visual tree dramatically. Before the rewrite, one of our most used user controls, when inspected with Snoop, consisted out of 61 different things, now there are only 3. Wherever possible we only added things to the visual tree on demand. (As you know in XAML even when you set things to Collapsed, they need to be created first).
Finally we were forced to write our own rich text rendering control as the built in RichtextBox is ridiculously slow and the visual tree of the RichtextBox is quite complex.
I don't know if this will apply to your situation but I would recommend that you investigate your user controls and see if they are complex. Maybe you have things that you could trim.
Low hanging fruits would be parts that are only rarely visible or can be created in a lazy manner. You could create these parts from code behind when necessary rather than having them in XAML. This should help you a lot.
Otherwise virtualization is your friend, if possible. In our case we couldn't do that unfortunately.
This sounds similar to a problem i was having. I posted the fix here: WPF UI Automation issue . Just posting for the benefit of searchers, as it took ages to resolve.
Following comment on link only answer, here is the crux of that post:
I did the following:
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB978520 (may not be required)
Downloaded Hotfix - - http://archive.msdn.microsoft.com/KB2484841 (definitely required even if you have Windows 7 / .NET 4)
Improved the code further (the validation was causing an excess of objects) - Why does WPF Style to show validation errors in ToolTip work for a TextBox but fails for a ComboBox?
It may be that only Number 3 was required, but it worked. Just posting here so people dont lose the days I lost in memory profilers etc.
User Control in your data template, is not completely bad idea but if you crave for performance then you should consider switching to lighter control. For example, having a UserControl just hosting a TextBox is very bad idea, as UserControl is made up of ContentControl, ContentControl hosts ContentPresenter and ContentPresenter will host TextBox so if you notice your Visual Tree, it has three new layer of UI Elements. Reducing Visual Tree will certainly improve the performance.
Most likely, I would suggest creating Custom Controls that may be a completely a new control having few dependency properties that can relate to data you want to present and you can have its own custom template in generic.xaml. Second, you can just simply derive a control from existing controls and redefine its default template in generic.xaml.
This approach will certainly work better as you will be reducing your Visual Tree, thus reducing Visual State Manager's job.
Changing theme or template will be slower then changing the element that hosts content. And let the element have the default template in its own generic resource dictionary.
Try moving all the resources up as
far as they'll go, preferably into
app.xaml
Check if you could use StaticResource
instead of dynamic ones, static ones
are alot faster
If possible, try using depedency
properties in your VMs, especially if
you have alot of them at once or if
they have alot of properties. That will keep wpf from having to do a bunch of reflection.
You mention you are using a DataGrid with, say, 100 rows. A likely culprit of your perf problems is that whatever datagrid you are using isn't doing virtualization, and so your visual tree is gigantic.
Normally, long startup time in WPF screens points to a large visual tree.
I'm not sure if you're using a datatemplate per row, or some 3rd party grid that binds columns, or what - but lets say you have 8 columns with controls. Depending on your grid/validation/etc, this could be a visual tree of 20-60 items per row. If you have a combobox, then each item in the dropdown may be created per row as well.
To fix this just takes watching the details, and taking measures as you go:
Use a virtualizing control as much as possible. This means using a virtualizingstackpanel inside list controls, and making sure your 3rd party controls do as well (many stock WPF controls do now by default)
Do not overuse UserControls, composite controls, etc. Adding depth adds time, and putting in extra visual tree depth in a datatemplate or other repeated area adds up fast.
If all else fails, show a simple screen and add controls through code to improve perceived performance
I am writing a small editor, based on a WPF (c#) TextBox. For some functionality the method getRectFromCharacterIndex(), which is only implemented in the TextBox-class is necessary. Furthermore I've got to do some syntax-highlighting in my program. Normally this is easy to handle in a TextBlock or a RichTextBox. Unfortunately these two Controls don't include Methods like the one mentioned above. Has anyone an idea, how to format and/or color single Characters in a normal TextBox with a small workaround?
Thank you very much for your answers!
I did the same effort in the past and I decided to move to this: http://wiki.sharpdevelop.net/AvalonEdit.ashx almost all the work you need is done here.
I'm writing an application that needs a log-like view, (similar to how an IM client displays messages in the conversation), with potentially many updates per second. Speed is an issue here; the application locking up due to a large number of incoming events is a possible problem. I need selection and basic text formatting, so manual rendering could get quite complex, I'd like to avoid it if possible. I'd also like to bottom-anchor the scroll bar, that is, if it's at the bottom, stay at the bottom when the new item is added. What would be a good way to implement this?
You can implement it very easily in WPF.
Create an ObservableCollection of Log entities and bind to a ListBox.
Give a DataTemplate for the ListBox.ItemTemplate.
*When running in real time you need either UI side or Data side virtualization
Check out my PaginatedObservableCollection so that the DataVirtualization will automatically function.
I think you should have a look at ListView/ListBox controls, they support UI virtualization and provide functionality you're looking for. Also you can improve performance by data virtualization/lazy loading - i.e. don't hold invisible items in memory and load required data on demand