The documentation for the Grid class states:
Starting in Windows 10, Grid defines new border properties that let you draw a border around the Grid without using an additional Border element. The new properties are Grid.BorderBrush, Grid.BorderThickness, Grid.CornerRadius, and Grid.Padding.
Does this make the Border class redundant? Why would I ever want to use a Border if I can do the same thing with a Grid and lay out children in a grid fashion if I so choose?
EDIT
I generally agree with Bart's answer, but there's a few things I would like to talk about.
Firstly, other layout controls (like StackPanel) do indeed have Border-like properties such as BorderBrush, BorderThickness and CornerRadius, so Grid isn't the only layout control which gets these new perks. But they are not attached properties provided by the Border class (or have anything to do with the Border class at all).
Secondly, I, too, thought that it would be a overkill to use complex layout control like Grid if I only wanted to add a border to a simple control like an image. But surely these layout controls would be optimized such that any impact to layout rendering speed would be negligible if they only contained a single child without any special layout constraints. So using a Grid instead of a Border shouldn't affect performance when it only has a single child.
Lastly, I decided to find out just how Grid achieves the border appearance. I created a simple Page containing a Grid with a border and a single Rectangle child, like this:
<Grid Background="Red" BorderBrush="Blue" BorderThickness="10">
<Rectangle Width="50" Height="50" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Yellow"/>
</Grid>
with the following rendering:
Upon inspecting the live visual tree, the Grid class does not add any additional elements to the visual tree to make the border appearance:
I suspect whatever mechanism it uses to create the border appearance would be the same as what the Border control does (maybe it creates an additional Visual in the composition layer).
So I'm not really convinced that the "simpler" Border control would be better to use because it looks like the Grid control is already quite performant. I can't see any evidence for the Grid control adding any extra overhead to the visual tree (when compared to what a Border would do to achieve the same effect).
So far the only reason I can think of why I should use Border instead of Grid is to express meaning. It's obvious what the Border control does, adds a border around a single element. Grid is a layout control used to lay out child elements within a grid (which, as it so happens, has the ability to add a border around its children too as an added bonus).
Your first question designing your UI should be do I need a Grid or another layout control (StackPanel, RelativePanel, Canvas, ...) based on the specific behavior of each control (see MSDN). Note that next to Grid, also StackPanel and RelativePanel have Border attached properties. These attached properties are bonus for you to not add another 'redundant' control in your XAML tree to wrap your layout control in.
Why is the Border control NOT obsolete? Let's say you want a border around an image (which is inside any of the above mentioned layout controls together with other items, so you can't reuse the layout control's border). Now you have 2 options:
wrap the image in a Border control.
wrap the image in a Grid (or other layout control) and abuse the attached properties.
My wording should be clear which one is best: pick the Border control. A rule of thumb is: keep your visual tree as small as possible. Opt for the simplest control doing the task. Placing an image in a Grid just for having the border around it adds to much extra overhead in your visual tree.
Related
I am creating a UWP app and I am using the VariableSizedWrapGrid control. I am binding the Width of the a ComboBox in the grid to it the ComboBox width resizes based on the entries in the list. ( I am using a simple property exposed through my view model.) When I had the items in a StackPanel with a Horizontal orientation it worked fine. See picture below
The challenge of course is that on a smaller screen I need the fields to wrap around. So I switched the StackPanel to a VariableSizedWrapGrid. However, when I do that, the Grid does not seem to be handling the resizing of the ComboBox correctly as I get what is shown below. (See the ComboBox is now cut off
Any suggestions on how to resolve this would be greatly appreciated.
You are using the wrong Panel for the job. The one you're looking for is a WrapPanel (which doesn't exist actually though), but there are some implementations available, eg.: http://codepaste.net/8gr5go
I have a series of items in a GridView.
I want to animate the TranslateTransform of a GridViewItem so that it is outside the boundary of the GridView. When I do, it is clipped. Is this type of transform possible?
Sadly, I don't think so. I had to do something similar a while ago and it turns out that the template of a GriView (and ListView, ListBox, etc...) contains a ScrollViewer control. The thing about the ScrollViewer controls is that they MUST define a clipped viewport to give the user the impression of scrolling. In fact, if you were to decompile the ScrollViewer control, you can see that it hard codes the clipped bounds, so you cant even change the template or style.
Things may have changed since I looked into this, and my investigations where on WPF not XAML in Windows 8, but I dont think that it would have changed based on your description of the issue.
Here is a SO question in relation to this topic: WPF clipping even when no clipping is desired - how to turn it off?
I wish to use XAML to create a calculator like interface.It should contain buttons upto 1000.
I've read about virtualizing stack panel but i'm not sure how to use it with a listbox and do data binding with that list for the content. Can you please help me with virtualizing stack panel concept
ListBox includes a Virtualizing StackPanel by default, so you dont need to worry about it, or how to implement it. FYI, the Virtualizing StackPanel only creates UI elements (in your case the Buttons), when they come into View. An aditional improvment is to switch on container Recycling:
<ListBox VirtualizingStackPanel.IsVirtualizing="true" VirtualizingStackPanel.VirtualizationMode="Recycling" />
I've got a WrapPanel which will contain several different custom UserControls. Depending on the scenario, I may need to filter down which UserControls are visible. My goal is that I can switch which controls are visible on the fly by showing/hiding the controls that need to be filtered - thus shifting the controls that are left showing, to the top-left of the panel.
Right now I am simply setting the Visibility property of the control to Visibility.Collapsed when I don't want them to appear. I thought that because I was using a WrapPanel, the rest of the controls would shift to the top-left of the panel.
Instead, after hiding some of the UserControls, the controls that are still visible stay exactly where they were before, and I am left with gaps between the controls that are still showing. I've opened my app in Silverlight Spy, and it shows that the UserControls are still actually there (which makes sense) but are simply invisible.
So my question is:
Is there a way that I can show/hide UserControls within a WrapPanel which allows the still-visible UserControls to slide to their new positions (all shifting towards the top left - similar to a StackPanel)?
I've debated removing the UserControls completely from the WrapPanel (I think this would work) and storing them in memory until they are needed. Then if I wanted to show/hide other controls, I would get them from my in-memory object. It seems like there should be a better way to do this though.
If anyone has any suggestions or advice, it would be greatly appreciated. Thanks!
-Lloyd
UPDATE:
XAML: (very simple)
<toolkit:WrapPanel x:Name="MyLayout" Height="300" HorizontalAlignment="Left" VerticalAlignment="Top" Width="400" />
Code-Behind: The UserControls are getting added dynamically:
MyLayout.Children.Add(oUserControl)
And they are getting set to collapsed dynamically as well:
oUserControl.Visibility = Visibility.Collapsed
I think I've found the problem. We added the WrapPanel to a ScrollViewer recently, and when I took the ScrollViewer out I was able to achieve the functionality I wanted.
I'm not sure why the ScrollViewer would have that effect though?
Also, I've found that I can leave the ScrollViewer in place and simply call .Measure() on the WrapPanel to update the layout.
Neither option makes 100% sense to me, but they do both seem to work.
I created a templated usercontrol from a button in order to use common states etc. What I dont get is how to scale a canvas inside the template. I created a little drawing with lines but they do not scale/transform with the control when I use it.
Most interesting would be if that is possible using xaml element binding (I am playing with SL3).
Regards Mario
I would use a Grid and set it's Height and Width to Auto. If yo addi items to the rows and columns and they are all set to stretch the stuff nside the grid will automatically resize. Not sure if that is what you are asking but that is what comes off the top of my head.