Toolbar isn't showing overflow when hosted in UserControl - wpf

Hosted in a Window, I have a main UserControl composed of other UserControls.
One of these contains a ToolBar with a few Buttons on it. I place this at the top of my main UserControl by setting it's Grid.Row property to 0. However, when making the Window smaller, the Buttons just disappear and no overflow is shown. I've messed with the overflow properties a bit but no luck.
Here's the UserControl containing the ToolBar.
<UserControl x:Class="TestProj.Views.ToolBarView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="706"/>
<ColumnDefinition Width="319"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<ToolBar Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Button Content="Button1" />
<Button Content="Button2" />
<Button Content="Button3" />
<Button Content="Button4" />
<Button Content="Button5" />
<Button Content="Button6" />
</ToolBar>
</Grid>
</UserControl>
Here's my main UserControl which is hosted inside of a Window, and hosts the ToolBar UserControl:
<UserControl x:Class="TestProj.MainControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-TestProj.Views"
mc:Ignorable="d" d:DesignHeight="737.239" d:DesignWidth="1026"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="256*"/>
<ColumnDefinition Width="430*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto">
</RowDefinition>
<RowDefinition Height="608*"/>
<RowDefinition Height="Auto">
</RowDefinition>
</Grid.RowDefinitions>
<views:ToolBarView HorizontalAlignment="Left" x:Name="OnyxToolBar" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" />
</Grid>
</UserControl>
And here's an example .gif of me resizing the Window, just the top where the UserControl containing the ToolBar is:

The problem is your fixed sized columns in your UserControl aka ToolBarView
you can not give to some control (does not matter if it is a ToolBar or not) a fixed size value and expect to have "dynamic size"
in your situation you could do something like this
change this
<Grid.ColumnDefinitions>
<ColumnDefinition Width="706"/>
<ColumnDefinition Width="319"/>
</Grid.ColumnDefinitions>
to this (for example)
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

Related

XAML window doesn't look like what I want

I'm learning about WPF and I'm creating a window in XAML.
The window should look like this:
But when I run the program it looks like this:
The code is the following:
<Page x:Class="WpfApp1.ProductsManagement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="ProductsManagement">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="420" />
</Grid.RowDefinitions>
<TextBlock
Margin="5"
Text="Search"
Grid.Row="0"
Grid.Column="0"/>
<TextBox
Margin="5"
Grid.ColumnSpan="2"
Grid.Column="1"
Background ="White"
Grid.Row="0"
Text="hi"/>
<DataGrid
Margin ="5"
Name="dataGrid"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="1"/>
<Border
Margin ="5"
Grid.Row="1"
Grid.Column="2"/>
</Grid>
</Page>
Any comments or suggestions are welcome.
UPDATE
I'm taking the following code as an example:
<Page x:Class="WpfApp1.Discussion"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:data="clr-namespace:BikeShop"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="Discussion">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<ListBox
Grid.ColumnSpan="2"
Margin="5"/>
<Button
Grid.Row="1"
Grid.Column="1"
Margin="5"
Content="Send" />
<TextBox
Grid.Row="1"
Margin="5"
Text="Type your message here" />
</Grid>
</Page>
And when I run the code it looks like this: (It works correctly)
Your RowDefinitions must be like this:
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
Right now you ask to fill the entire page for the first row and set the second row to a height of 420.
You must define a specific value for the first and * for the second.
You do not see the error in the designer because you set the second row to 420. Obviously you see the first row at 30. But when you go to fullscreen, the first row gets bigger.
Because your Row heights are incorrect. replace your RawDefinitions with:
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>

Resizing WPF Prism Regions

In a WPF Prism app, I have two separate views in two separate regions, say LeftRegion and RightRegion. I would like to be able to drag the edge of LeftRegion (ie. the view in LeftRegion) like a gridsplitter works. Any ideas on how to accomplish this? Thank you.
EDIT: Here is the ShellView.xaml called by bootstrapper.cs that defines the regions.
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height ="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="215"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentControl Grid.Column ="0" Height ="500" prism:RegionManager.RegionName="LeftRegion" />
<GridSplitter Grid.Column ="0" Width="5" HorizontalAlignment="Right" VerticalAlignment="Stretch" ResizeBehavior="CurrentAndNext"/>
<ContentControl Grid.Column="1" Height ="400" prism:RegionManager.RegionName="RightRegion" />
</Grid>
Since Prism regions are nothing but UIElements, typically ContentPresenters, you should be able to use a GridSplitter as usual:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
prism:RegionManager.RegionName="LeftRegion"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentControl prism:RegionManager.RegionName="LeftRegion" />
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<ContentControl Grid.Column="2" prism:RegionManager.RegionName="RightRegion" />
</Grid>
</Window>

Adjust TextBlock on a Button within a Grid

I have two buttons on a grid. On the right button there should be some text shown left aligned and another text right aligned. In all my tries so far the two strings are positioned in the center of the button and not left and right.
Once this is solved I need some space between the text and the left/right borders of the button.
Who can help?
My XAML-code so far to start:
<UserControl x:Class="MyNamespace.MyClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="900">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button>
<TextBlock Text="left button"></TextBlock>
</Button>
<Button Grid.Column="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="left"></TextBlock>
<TextBlock Text="right" Grid.Column="1"></TextBlock>
</Grid>
</Button>
</Grid>
</UserControl>
DonĀ“t blame me for not putting this stuff in a ResourceDictionary. Just wanted to make the example simple.
You need to add HorizontalContentAlignment="Stretch" to Button in order for contents to take up full space. After that, to make space between text and button borders, just add two more grid columns at first and last position.
XAML:
<UserControl x:Class="MyNamespace.MyClass"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="900">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button>
<TextBlock Text="left button"></TextBlock>
</Button>
<Button Grid.Column="1" HorizontalContentAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<TextBlock Text="left" Grid.Column="1"></TextBlock>
<TextBlock Text="right" Grid.Column="3"></TextBlock>
</Grid>
</Button>
</Grid>

Binding Grid Column Width inside UserControl to parent Grid Column Width

I have a WPF Grid with two rows.
First row contains 4 columns and each column contains a Button.
Second row contains user control with colspan of 3.
The custom control contains another Grid with two columns.
I would like to set the width of the first column in UserControl's grid to the width of the second column in the MainWindow's grid.
In the example below "nested column 0"'s width should be the same as "Column 1"'s width.
I tried with ElementName but it did not work out.
Any ideas how to do it?
<Window x:Class="TestElementName.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:trace="clr-namespace:System.Diagnostics;assembly=WindowsBase"
xmlns:local="clr-namespace:TestElementName"
Title="MainWindow" Height="200" Width="600">
<Grid Tag="YeahGrid" Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" Tag="Hallelujah" x:Name="ColDef2"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0">Column 0</Button>
<Button Grid.Column="1" Grid.Row="0" MinWidth="180">Column 1</Button>
<Button Grid.Column="2" Grid.Row="0" MinWidth="115">Column 2</Button>
<Button Grid.Column="3" Grid.Row="0">Column 3</Button>
<local:ucButton Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" BorderBrush="Red" BorderThickness="1" />
</Grid>
</Window>
User control is as follows:
<UserControl x:Class="TestElementName.ucButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:trace="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0">nested column 0</Button>
<Button Grid.Column="1">nested column 1</Button>
</Grid>
</UserControl>
Thank you!
You can do this using a SharedSizeGroup. This allows you to link the width of designated columns in multiple Grids. (It also works for row height!)
First you need to define a SharedSizeScope on a control that encompasses all of the columns that will share widths. You can use your YeahGrid for this:
<Grid Tag="YeahGrid" Name="grid" Grid.IsSharedSizeScope="True">
Then set the SharedSizeGroup property on the columns you want to align. In the Window:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto" Tag="Hallelujah" x:Name="ColDef2" SharedSizeGroup="HallelujahSSG" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
And in the UserControl:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="HallelujahSSG"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
Now the widths of all Grid columns with the same SharedSizeGroup name are linked, effectively bound to the width of the column that requires the most space (in this case Column 1 in YeahGrid).
In your UserControl Xaml, you mentioned both ColumnDefinition width = "Auto". On that place please add the MinWidth attribute as per your requirements.
For your scenario you can add ---
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="180"/>
<ColumnDefinition Width="Auto" MinWidth="115"/>
</Grid.ColumnDefinitions>
Because you are using in mainwindow like this
<Button Grid.Column="1" Grid.Row="0" MinWidth="180">Column 1</Button>
<Button Grid.Column="2" Grid.Row="0" MinWidth="115">Column 2</Button>

WPF: Is VerticalAlignment inherited by nested containers?

I'd like to have the nested containers inherit that property, but when I set it in the outermost one I'm not sure if it's working. It either is working but I'm not getting the results I want, or maybe I'd have to set up a property somewhere for it to carry.
Assuming that a) it is possible to do it and b) I'd have to change a property somewhere, would that have any side effects I should be aware of?
EDIT
Ok, here's an example:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Grid.Row="1" Grid.Column="1"></Slider>
<Button Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
What I would like to have, without having to do it manually:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Label VerticalAlignment="Center" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox VerticalAlignment="Center" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button VerticalAlignment="Center" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label VerticalAlignment="Center" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider VerticalAlignment="Center" Grid.Row="1" Grid.Column="1"></Slider>
<Button VerticalAlignment="Center" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
Although I'm not really sure there was any difference here. It's not a deal breaker or anything, but I'd like to do it this way.
VisualTree inheritance is not universal. The dependency property specifies that it will inherit down the visual tree when it is declared. In this case, verticalalignment is not.
The only way to get a consistent vertical alignment is to use a style. And you can't use an implicit style across different types of controls. So you need to create a named style, place it in the resources of the container. Add a setter to the style to set the vertical alignment to whichever value you want. Finally reference the style in all the controls to which you want it applied.
Here is your example done with styles...unfortunately you're not saving much typing however if your style did something like Set VerticalAlignment and the FontFamily, then you're saving space...If you think of it like CSS then WPF Styles are easy.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Width="300" Height="100">
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style x:Key="setVA" TargetType="{x:Type Control}">
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Grid.Resources>
<Label Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="0">Text</Label>
<TextBox Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="1">I'm on the Internet</TextBox>
<Button Style="{StaticResource setVA}" Grid.Row="0" Grid.Column="2">Don't click me</Button>
<Label Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="0">Text2</Label>
<Slider Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="1"></Slider>
<Button Style="{StaticResource setVA}" Grid.Row="1" Grid.Column="2">Click the other guy</Button>
</Grid>
</Window>
There's more information on using styles on MSDN

Resources