I am new to professional development of UI application. I wonder what the normal approach to decide the layout of the each UI element.
Do people hard-code the size elements according to the design time monitor size? And later scale the UI size dynamically?
Or do people use some dynamical approach to set each UI element proportional according to screen size? I meant if there's a method dynamically to set controls size proportional to screen size and that ratio is hard-coded by programmer. Obviously, Dockpanel or viewbox are automatic adjusting. Or do people usually decided size upon design time?
Or there're other common approach?
Its generally recommended to have size of the elements proportional according to screen size. WPF has lot many features to achieve these functions. Since you where new to WPF, have brief knowledge about the WPF Panels. Also if you would like to stick with the existing layout and you need to expand the layout proportionally make use of ViewBox in WPF.
There is no simple answer to this. The WPF composition does a lot of hard work for you, if you let it.
If I can help it, I do not specify Width's and Height's but I would be lying if I said that I never do. In some data entry applications, there is no choice but where I do have a choice, I will let the WPF composition system do the work for me. Margins are the only layout property that will always get a look-in.
The WPF Composition system
The WPF Composition system will pass over your logical tree twice, once to measure the elements and once to arrange the elements based on the collected information. Some elements, such as panels, will attempt to take up as much space as they can. Some elements will attempt to constrict their contents as much as possible. Some elements will take up only the space they need.
An example is if you put a TextBox in a Grid without specifying Width's and Height's, the TextBox will take up the entire 'content' area of the Grid. If you do the same with a TextBox and a StackPanel, the StackPanel will constrain the TextBox to the MinHeight of the TextBox. Put a CheckBox in the Grid and it will take up only the area it needs.
Conclusion
There is no simple way to learn this other than to play.
I recommend reading the following links
WPF Architecture
Trees in WPF
They are both long reads but worth while. They will give you the theory you need to search for more practical applications of WPF and there are a lot of good blog entries out there that cover this topic.
Related
I need to develope a WPF custom control to show the layout and connectivity of nodes in a wireless mesh network. The user needs to be able to drag the nodes around. The canvas should grown and Scrollbars should appear as required if elements get draged off the available space. The ability to zoom in/out might be required.
My first take on this is to use a ListBox derived CustomControl with a Canvas based ItemsPanelTemplate. To get things moving Im using Josh Smiths DragCanvas that allows UIElements children of the canvas to be dragged around. My "node" class is not currently UIElement derived (the DragCanvas is currently working with the ListBoxItems that wrap my nodes).
1. Is this a bacially sensible approach or should I be abonding the ListBox idea and going something lower level?
2. I have to overlay the inter node link lines - not currently sure how to go about this (as a UIElement class that is part of the ControlTemplate?)
3. A few people seem to be having a headache with scrolbars in Canvases - is this going to be an issue?
Any general or specific advice most appreciated.
Wow, not bad as a control!
I am doing something similar, but it is not so simple.
1) IMHO, the DragCanvas is a basic way to host+drag elements. Since you will have to host labels (nodes), arcs and labels again (arcs' weight), I think the DragCanvas would be harder than write a custom control by yourself.
Not everything comes easy with templating: sometime is much better the "old" approach winforms-like, or even a hybrid way.
2) As stated, I'd create a Canvas-derived panel, which will host several UIElements (labels, arcs, etc). All of them should be governed by a model+viewmodel. That's a bit harder at the beginning, but it will give you a lot of satisfaction and flexibility in the future.
3) I don't think the Canvas will give you any headache! A Canvas full of elements has always a size of zero. That leads "headaches" for those trying to add a scrollviewer.
Instead, the Canvas-derived class (above) should override the MeasureOverride method, so that its size will fit any of the hosted objects. However, it is a bit annoying the fact you cannot use negative coordinates (it will cause scrolling problems).
It's hard to describe in few lines all the work behind a similar "editor". The task isn't easy, and the problems are many.
Hope it helps, anyway.
Cheers
folks
I have heard from a coworker that I - as a designer using Microsoft Expression Blend - should avoid using excessive nesting of panel elements, because they are computationally expensive.
For example, I tend to create the mainwindow with header and custom statusbar with grid, and then take the top panel and put a grid inside it, and if I have a message inside a rectangle on the already gridded top panel I create yet another grid, etc.
As a very layout-oriented disigner (who wants to use every screen most efficiently whatever the screen dimensions are) I know this is the best way to do it considering absolute control and flexibility, which prevent the window to resize in "unpredictable" ways ;oP
BUT...
...this friend of mine said that, if you have, say, five grids nested inside one another, if you pass the mouse over them, you generate five mouse events, which is costly.
Also, if you have too many calculations due to the too many containers asking for children sizes before the actual rendering, it can also be costly.
I had some previous experience with PyGtk, and I must say I used A LOT o layout panels for all my scripts, and even the resizing of windows never seemed to me to be specially costly, except when I had some complex canvas drawing needed to be recalculated.
Does anyone have any experience or know anything about it?
Thanks a lot for reading
There's no straight-forward answer to this, but obviously the more elements you have participating in layout, the longer the measure and arrange phases are going to take for the window. Depending on which features of which Panel types you use it could be more or less costly, but for sure the more you use the more overhead there will be during the layout calculations. You can learn more about how the layout system works by reading that entire MSDN article.
In the end this is something that, unless you've gone crazy, will not often be an issue. To find out if it is causing problems for your app I suggest using the WPF Performance Suite to do some performance testing.
Wouldn't worry about it that much, i for one did not have problems with it so far. Apply some common sense, what panels are needed in which case? Do you really need yet another panel to achieve your goal or not?
The MSDN article on this issue might be of interest since it explains a few things which are not straightforward: Optimizing Performance: Layout and Design
I am new to WPF environment and I am experiencing some problems like if there are alots of things how do we manage them.for example I have three borders each of same size same location and they contains controls like textboxes etc etc we construct them sequentially but when it comes to edit we get in trouble modifying the border that is at bottom.
So in short how do we manage many controls on single page so that it remains easy to edit
Not sure I completely understand your concerns, but here are several point that make editing WPF UI pretty easy:
Correct usage of layout panels. If you will use approach with absolute positions for each control then it might become a nightmare to move or resize some of your controls. Correct layout (and panels such as DockPanel/StackPanel/etc) might help you a lot.
Incapsulating repeatable parts. WPF has a lot of feature to avoid repeating UI code. I'm talking mostly about Styles and Control templates at the moment. If you have your borders repeating through the entire window, maybe you should think on extracting this border as a ControlTemplate for ContentControl for example?
but I've found that encapsulating controls such as borders, textboxes etc in User Controls helps to keep things well managed (not to mention helps reduce code), similarly using a Resource Dictionary to store styles/animations is useful for very big projects (remember though that the local resources will take precedence when applied so remove them if they not in use)
furthermore, using Layout Panels such as Stacks,Grids and Dockpanels allows you to collapse User Controls when not needed or otherwise (also I've found that for some reason, Grids allow controls to overlap (when items are not correctly ordered in Grid Rows and Columns) which can lead to some elements not being seen in design.
Plan your layout properly and think through which Panels would be best for them, having to go back much later and change can be annoying (though admittedly it happens).
Also remember to use partial classes to properly structure your stuff, having to read through 1000+ lines of code to find something can be a nightmare.
I'm looking for way to present equally sized elements in a fixed number of rows and any number of columns. (Think of iTunes' or Picasa's album view. I believe some platforms refer to this as a 'gridview')
A WrapPanel would do the job, but I'm binding against a very large collection of objects, so I need virtualization.
I've been looking around the web, and found both commercially available VirtualizationWrapPanels and blog posts on how to implement your own VirtualizationPanel, but I can't seem to find any simpler solutions.
Is it possible to arrange virtualized databound items in a grid-style view (fixed number of rows) with standard WPF components?
I've recently had to have a hunt round for similar functionality and struggled to find anything that was production ready.
I found a series of articles and sample code that contain a Virtualizing Tile Panel.
I've been using it and it has been fairly stable. There were some changes that needed to be made though. We had to add some of the keyboard control into the panel as it wasn't implemented, tabbing needed to be changed as well as adjusting tile sizes, etc. It's a good starting point if you decide to roll your own.
One major caveat though was that it also MUST have a parent that is constrained to a limited size else it errors out. This is not normally an issue as you will want it to be limited in size so you can enable scrolling. There may be a solution to this particular problem but we didn't have time to investigate.
A quick-and-dirty solution is to use a list (in your case a horizontal one) of "grouping items" (in your case vertical ones) which will determine desired number of rows. Virtualization will occur on the "groupers".
It is the responsibility of the Panel to provide Virtualization. Unfortunately the framework only provides a virtualizing StackPanel:
http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingpanel.aspx
There is a very good blog post that provides a virtualizing WrapPanel here:
https://blogs.claritycon.com/custom-panels-in-silverlight-wpf-part-4-virtualization-7f3bded02587
Another alternative is to use a DataGrid, this will virtualize for you.
WPF is great because there are many ways to achieve your goals. For example, from what I understand, adorners can add some controls to a UI element, but I think that the same behavior can be achieved through a custom control that contains the additional element.
So, my question is: when should I prefer adorners to a more complex (but I think, more flexible) custom control?
Please consider that I'm extensively using MVVM pattern and I would like to bind commands to the additional element.
In particular, I'm designing a diagram designer application and I would like to add connection points to my shapes. Another example where I should decide between a custom control and an adorner is a line which shows a label automatically positioned to "follow" the line.
Thank you
Adorners require a little more work than using ControlTemplates for most purposes. If you want the additional functionality that adorners provide, use them. Otherwise use ControlTemplates.
Here are the main features that Adorners bring to the table:
Because adorners are on a separate layer, the visual can extend beyond the adorned element, even if the adorned element is clipped.
Because adorners are on a separate layer, they are generally not obscured by the AdornedElement's container or by sibling controls.
Adorners are automatically notified of all changes in the size and location of the adorned element, allowing responses to layout changes that are not as easily achieved with ordinary controls.
Adorners can be applied to panels and to existing controls without making any changes to their templates or otherwise. This makes them good for providing manipulation handles or visual feedback on arbitrary controls.
In many scenarios you will create adorners only for a few "active" items out of hundreds or thousands. Implementing the same functionality using ControlTemplates can be dramatically less efficient if you have to add an additional Panel to the template: Every single instatiation of the template will have the extra panel, whereas there would be just one adorner.
Here are some of the potential costs associated with using adorners as opposed to ControlTemplates:
You must write code to call .GetAdornerLayer() and .Add() and to manage the lifetime of the Adorner
You must either write rendering code for your Adorner or add code to include a Control as a child of the adorner so you can use a ControlTemplate with it
You'll generally do your custom measure/arrange calculations in code (unless you are using a ControlTemplate within your adorner)
You'll need to forward RoutedEvents to the AdornedElement if you want them to be handled by the target control
You'll need to add a DataContext="{Binding AdornedElement.DataContext}" if you want to bring the DataContext across
It appears that visible Adorner is scanned on every layout pass, so having many thousands of adorners onscreen at once can result in noticeable slowdowns. (Ordinary visuals only have their measure/arrange code called when something that directly affects them changes.)
Having more than 144 adorners is not supported, so control templates are more suitable if there's any risk of getting close to this limit.
In your particular examples, there are no clear-cut right answers.
I'd lean toward using a ControlTemplate for connection points since you will presumably need a way to specify the locations of the connection points, and the ControlTemplate is already defining the layout the item itself. On the other hand, if the connection point information is data-driven and only appears on the active control (or the control being dragged over) it might be better to use adorners to get the performance advantages and simplify the individual ControlTemplates.
An automatically positioned label could be a good fit for an adorner from a measure/arrange calculation point of view if the lines are anything but simple straight lines, but if you will potentially have ten thousand of these visible at once I would be concerned about performance.
Without knowing more about your application it is hard to say more than this.