Left HorizontalAlignment on a Grid - c#

I'm trying to use HorizontalAlignment="Left" in the following situation:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Grid HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Background="Gray" Text="Small Text" TextWrapping="Wrap"/>
<TextBlock Grid.Column="1" Background="White" Text="This is a very large amount of text" TextWrapping="Wrap"/>
<TextBlock Grid.Column="2" Background="Gray" Text="Medium amount of text" TextWrapping="Wrap"/>
</Grid>
</Window>
My goal is to be able to resize the window, and have the three TextBlocks resize themselves proportionally. This works, but the grid is putting some blank space to the right of the final column, and as I try to resize towards the final column, the columns start to shrink. I want this shrinking behavior, but I don't want it to start until there is no more white space to the right of the rightmost column.
I can't use a UniformGrid as the text lengths can vary, and no other built-in WPF control that I've seen has the ability to resize all children when the parent size changes. I've looked into creating a custom panel, but that seems to be more trouble than it's worth. I feel like something much more simple can be done here.
Any suggestions or ideas are appreciated.

You'll have to build your own custom panel, and handle the case where the AvailableWidth is less then the panel's children DesiredWidth
Panel layout in WPF (Grid is a Panel) is a 2 step process, in the first pass the Panel iterates over its children and provides them with the panel's AvailableWidth. The children respond to this by computing their DesiredWidth.
In the second pass the Panel arranges the children according to their DesiredWidth. In this second pass you have access to the width that all the children (in your case, TextBlocks) require. If it is less than the panel's available width you can compute a percentage to give each one so that they appear to shrink uniformly.
Here's a resource that shows how you can create your own custom panel

What about this?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>

Related

Dynamic Resizing of Grid Using Auto with Split Preference

I want to achieve the following in XAML (WPF):
By default, maintain a 60%-40% split for a grid with 2 horizontal elements
If the second element is blank (or smaller than 40%), allow the first element to take up the remaining space if it needs it
If the first element is blank (or smaller than 60%), allow the second element to take up the remaining space if it needs it
This feels like a "preferred width" instead of a "MaxWidth" type thing. Additionally, the first element is left aligned and the second element is right aligned.
Some things I've tried that don't work (also couldn't find if this question was answered - searches didn't result in what I wanted)
This doesn't work because it sets both to columns to a specified width:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Test1"/>
<TextBlock Grid.Column="1"
Text="Test2" />
</Grid>
This doesn't work because although if both take up 100% of their spaces, it looks fine, but auto won't allow one element to overflow into the other area if a "MaxWidth" is set - I would like "MaxWidth" to almost be like a "PreferredWidth":
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MaxWidth="60% of the pixels"/>
<ColumnDefinition Width="Auto"
MaxWidth="40% of the pixels" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Text="Test1"/>
<TextBlock Grid.Column="1"
TextAlignment="Right"
Text="Test2" />
</Grid>
Is there a way to achieve (what seems like a relatively easy product spec) through just XAML? And if not, what are the alternatives?

Limit WPF control size to a certain proportion / percentage of the parent control [duplicate]

In WPF, I want set a controls width to be, say, 97% of it's Parent controls ActualWidth property. How can I do this?
You can use Grid panel. E.g:
<Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.97*"/>
<ColumnDefinition Width="0.03*"/>
</Grid.ColumnDefinitions>
<Button Content="97%"/>
<Border Grid.Column="1" Background="Green">
</Border>
</Grid>
</Border>
Grid will occupy 100% of available border's size. First column will use 97% of it. And the rest 3% are given to border in the second column.
Hope this helps.
Cheers, Anvaka

XAML How to arrange an element after a centered one

I want to create a button that will display some text together with a status icon inside. The text should be centered and the status icon should go right next to the text. Something like this:
I didn't find a way how to center only the text and then positioning the icon after the centered text. Right now I am using a Grid solution which centers the text and aligns the icon to the right.
<Button VerticalContentAligment="Stretch" HorizontalContentAligment="Stretch">
<Grid>
<TextBlock VerticalAligment="Center" HorizontalAligment="Center"/>
<Image VerticalAligment="Center" HorizontalAligment="Right"/>
</Grid>
</Button>
It's not what I want but it's working for the button's size I have at the moment.
I know that this can be accomplished using some binding magic but it seems too simple for this. It will be great if you can point me to a solution without binding magic but I will grateful even for one with it.
A Grid with 3 columns should work. When the left and right columns have equal width, the middle one is automatically centered.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" VerticalAlignment="Center"/>
<Image Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</Grid>

WPF Create Sidebar Navigation

I am curious about how to create a sidebar navigation something like:
I tried using an uniform grid but there ended up being too much spacing between "buttons" and I'm not sure if it's possible to modify the tab control to act like full width buttons instead of overhead tabs.
Also if if its possible to add icons that would be a huge plus.
You can make a Gridcolumn in your Standard grid with your wished Width. The into this Column you can put a stackpanel which fills your buttons from top to bottom.
Like That:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<Button Height="40">Test</Button>
<Button Height="40">Test2</Button>
</StackPanel>
</Grid>
It would look like this:
If i missunderstod you please tell me and im gona edit it.
To add Images you can then create another grid in your Button with two columns: Like this:
<Button>
<Grid Height="40" Width="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="pack://siteoforigin:,,,/Resources/dll.png"></Image>
<TextBlock Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center">Text</TextBlock>
</Grid>
</Button>
Note that you have to set your grid to Width="200" like you set your main Grid.Column because the Grid would not be the whole width of the button if you would not set it too 200.
Then the List would look like this:

Handling Different Font Sizes Due To Display Properties in a WPF App?

My group is building an editor-type app in WPF. One thing we noticed is that on my WinXP machine, running with the "windows classic style" theme, the text on buttons is fits fine. However on my friend's machine, who's running with the "windows xp style" theme, the font size is bigger so text on buttons get clipped at the bottom.
Is there a way to handle this nicely, like automatically resizing controls to fit the text?
I hesitate to manually resize the button to fit his layout as anyone else can have totally different settings through the Display Properties and Accessibility Options.
Thanks!
A WPF button will automatically resize to fit the content that it has been given, however it will only do this when it is inside a container that does not enforce size and its size has not been set manually. To prove this mess around with the font size in the following code snippet:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button
Grid.Column="1"
Grid.Row="1"
FontSize="24"
Content="QWERTY"/>
</Grid>
I guess that your buttons haven't resized because you have constrained them. To fix this you need to decide how you want them to resize (which can be very complicated when elements would overlap if they just grew blindly) and if none of the supplied panel types perform the growth behaviour that you are looking for then you may need to write your own that does.
Have you hardcoded element sizes using Width and Height properties? In WPF the recommended way to do this is to use the several layout containers.
The following is an example of a grid which lays two buttons at the bottom and a textbox at the top.
<Grid>
<Grid.RowDefinitions>
<!-- TextBox row with unspecified height. -->
<RowDefinition Height="*"/>
<!-- Button row with automated height so it resizes to
fit the content -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Textbox on first row. -->
<TextBox Margin="3" Name="textBox1" Grid.Row="0" AcceptsReturn="True" />
<!-- StackPanel which lays the two buttons at the bottom horizontally.
RightToLeft is specified so that the first button appears on right.
-->
<StackPanel Grid.Row="1" HorizontalAlignment="Right"
Orientation="Horizontal" FlowDirection="RightToLeft">
<!-- The buttons. Only padding and margin are hardcoded so these
can resize to the contents -->
<Button Padding="3" Margin="3">OK</Button>
<Button Padding="3" Margin="3">Cancel</Button>
</StackPanel>
</Grid>

Categories