ColumnDefinition MinWidth doesn't work correctly - wpf

I'm using a Grid in WPF (xaml) and I'm have some strange effect when using the MinWidth property in a ColumnDefinition. For example, when I use 9 ColumnDefinition and every ColumnDefinition has the 'Width="*"' property and one of the middle columns also has a MinWidth property then the size of the other columns is wrong.
Well, it's hard to discribe but this xaml code illustrates it nicely:
<Grid Width="500">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" MinWidth="250"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="Green"/>
<Border Grid.Column="1" Background="Blue"/>
<Border Grid.Column="2" Background="Red"/>
<Border Grid.Column="3" Background="Yellow"/>
<Border Grid.Column="4" Background="Purple"/>
<Border Grid.Column="5" Background="Orange"/>
<Border Grid.Column="6" Background="Azure"/>
<Border Grid.Column="7" Background="LightBlue"/>
<Border Grid.Column="9" Background="LightGreen"/>
</Grid>
When you run this xaml code you'll see that the first 3 columns have a different width than the last 5 columns. Where I expected all of those to have the same width.
Does anyone know if this is a bug. And if there is a way to do this correctly.
Thanks in advance.

I see what you mean - the columns to the left of the yellow one are wider than the columns to the right, even though they are meant to be given the same proportions.
I would say it's a bug, especially when you consider that the following workaround works:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="1.0000001*" MinWidth="250"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
I would guess that this bug is related to how the columns are grouped by width...

It looks like it just the way it works. You've limited grid in 500 points, and said: hey, give all grid columns the same width, but also this column should be at least 250 points. Now the question from WPF to you: Dude, I see you asked me to give each of 9 column at least 250 points, how can I do this in 500 points? And it makes a decision, to respect your minimum width, but the price is - width of the rest columns.
As for the way to do this correctly. What do you mean? What do you want?

Related

How to make binded grid size to be proportionate value?

<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Width1}*" />
<ColumnDefinition Width="{Binding Width2}*" />
<ColumnDefinition Width="{Binding Width3}*" />
</Grid.ColumnDefinitions>
I basically want whatever the value of Width1, Width2 ... to have an asterisk after it.
So let's say the Width1 is 5, I want it to be 5* so that it will be a proportionate value.
I'm fairly new too WPF myself but I would do something like this:
And then you can do your binding on the WidthValString:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding WidthValString}" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
I'm assumming you will do this with ColumnDefinitions because you cannot have a grid with a width of 5*. As far as I know it has to be an integer. (With ColumnDef/RowDefs you'll be fine)
If this is not what you want, please specify your question!

Grid columns shows 1px if all is set to Auto

Why the Column 1 and 3 shows 1px if is empty?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Background="Red"/>
<Border Grid.Column="1" Background="Blue">
<TextBlock Text="123"/>
</Border>
<Border Grid.Column="2" Background="Azure"/>
</Grid>
Is bug or something that i don't understand?
Is possible to make Auto and Hide the 1px.
Edit: Need UseLayoutRounding="True". I have on Window.
Add and extra: <ColumnDefinition Width="*"/> and works fine.

Bind MaxWidth to calculated Auto value

I have a datatemplate containing this section. The second column is used for a GridSplitter.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" MaxWidth="100"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid>
What I am trying to do is to bind the MaxWidth of the first column to the width of its content instead of a hardcoded width value.
The idea is that the user can make the column narrower than its content but not wider.
Is this possible with simple binding?
OneTime Binding to Actual Width of the content UserControl did the trick!
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" MaxWidth="{Binding ActualWidth, ElementName=ColumnContent, Mode=OneTime}" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid>

Auto Sizing between grid columns

I have two controls and a GridSplitter .
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<UserControlOne Grid.Colum="0" Visibility="{Binding MyProperty1}"/>
<GridSplitter Visibility="{Binding MyProperty1}" m:Splitterbehaviour.Apply= true/>
<UserControlTwo Grid.Colum="1" />
</Grid>
I am trying to show/hide the UserControlOne with the MyProperty1 which is working fine but when it is hidden i want the UsercontrolTwo to take whole page space. I could easily achieve this by using a stack or dock panel. But if i use the stackpanel or dockpanel my GridSplitter wont work.(I have a behaviour set to GridSplitter which will identify the first column and it will help to resize the first and second column)
I don't see how that splitter is working
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<UserControlOne Grid.Colum="0" Visibility="{Binding MyProperty1}"/>
<UserControlTwo Grid.Colum="1"/>
</Grid>

WPF: getting AccessText in ScrollViewer to wrap

I have a Grid containing a ScrollViewer containing AccessText. I want the AccessText to take up the full width of the ScrollViewer, which should take up the full width of the Grid, without any overflow. Currently, the contents of my AccessText are cut off on the right side of the screen instead of wrapping. I have tried setting AccessText.TextWrapping to Wrap, WrapWithOverflow, and I've also tried removing the property entirely. I switched to using a Grid instead of a StackPanel because I thought that might affect how the contents are sized, but that hasn't helped. Here's what I have:
<Grid MaxHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<AccessText Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
When you set ColumnDefinition Width to Auto, the ScrollViewer within it won't be limited by the "visible Width" of the Column, so it will still take up as much horizontal space as it needs. With the xaml you posted, I think Width="*" will suit your needs. For the ScrollViewer, it seems like you don't want it to be able to Scroll horizontaly but only verticaly? In that case, set HorizontalScrollBarVisibility="Disabled". Otherwise you'll get a Horizontal ScrollBar.
<Grid MaxHeight="40">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<AccessText TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
If you simply want the AccessText to wrap indefinitely, modify your second ColumnDefinition from Auto to * and move the AccessText outside of the ScrollViewer as seen below...
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<AccessText Grid.Column="1" TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</Grid>
The reason the text would not wrap is because the second ColumnDefinition was set to Auto; which essentially does not force a bounds around the AccessText.
If you want to keep the ScrollViewer try this...
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
<AccessText TextWrapping="Wrap" Text="{Binding MyLongTextField}"/>
</ScrollViewer>
</Grid>
This ended up giving me what I wanted:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Whee a label:" Grid.Column="0"/>
<ScrollViewer Grid.Column="1" MaxHeight="40"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<AccessText Text="{Binding CRData.Error}" TextWrapping="Wrap"/>
</ScrollViewer>
</Grid>
Thanks to Meleak and Aaron for the suggestion of using * for the column width instead of Auto, and to Meleak for suggesting Disabled for the horizontal scrollbar instead of Auto.

Resources