WPF ListBox with bottom-alignment displays at top within StackPanel - wpf

I have the following XAML:
<Window x:Class="test_stacking.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Background="AliceBlue">
<Canvas Background="Red">
</Canvas>
<ListBox Width="200" VerticalAlignment="Bottom">
<TextBlock Text="One" />
<TextBlock Text="Two" />
</ListBox>
</StackPanel>
</Window>
I would like the Canvas to be on top, and the ListBox to be on the bottom. Since the default orientation for a StackPanel is vertical, I thought I would get the Canvas and the ListBox, in that order, stacked within the StackPanel.
But instead, I get what is shown below: the ListBox is on top, and the Canvas does not show at all. What am I doing wrong?
.NET FW 4 Client Profile, Windows 7, VS 2010.

If it is not mandatory to use StackPanel then you can achieve that by using Grid's * sizing.
Here is 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="Window1" Height="500" Width="500">
<Grid Background="AliceBlue">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Canvas Background="Red">
</Canvas>
<ListBox Grid.Row="1" Width="200" VerticalAlignment="Bottom">
<TextBlock Text="One" />
<TextBlock Text="Two" />
</ListBox>
</Grid>
</Window>
Output:
Or
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="500" Width="500">
<Grid Background="AliceBlue">
<Canvas Background="Red">
</Canvas>
<ListBox Width="200" VerticalAlignment="Bottom">
<TextBlock Text="One" />
<TextBlock Text="Two" />
</ListBox>
</Grid>
</Window>
Output:

Since you haven't set any height or width to the canvas, the height and width for the canvas is set to zero and thats why its not shown in the UI.
Try this
<StackPanel Background="AliceBlue">
<Canvas Background="Red" Width="200" Height="200">
</Canvas>
<ListBox Width="200" VerticalAlignment="Bottom">
<TextBlock Text="One" />
<TextBlock Text="Two" />
</ListBox>
</StackPanel>

Related

Change the size of checkbox rectangle without changing its content

In my following WPF app, how can we change the size of the CheckBox without changing the size of its content (an Segoe MDL2 Assets icon). I would like to see the checkbox rectangle to be the half the size of its content (an icon). If I set the width and height of the checkbox to 10 it reduces the content size (icon) as well:
<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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<CheckBox VerticalContentAlignment="Center">
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="20"/>
</CheckBox>
</StackPanel>
</Grid>
</Window>
Display of the above XAML:
You could move the TextBlock out of the CheckBox. Something like this:
<StackPanel Margin="10">
<Label FontWeight="Bold">Application Options</Label>
<Grid VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox RenderTransformOrigin="0.5,0.5" VerticalAlignment="Center">
<CheckBox.RenderTransform>
<ScaleTransform ScaleX="0.5" ScaleY="0.5" />
</CheckBox.RenderTransform>
</CheckBox>
<TextBlock Grid.Column="1" Text="" FontFamily="Segoe MDL2 Assets" FontSize="20"/>
</Grid>
</StackPanel>

Change the height of the title bar

Question: Can we change the height of the title bar displayed in MahApps.Metro?
Details: For instance, in the following XAML example from the MahApps team, I want to display the content Deploy CupCake - of the TextBlock - below the image of the CupCake. So I removed the Orientation="Horizontal" from the StackPanel in the following XAML. As shown in the snapshot below, the content Deploy CupCake is now showing below the image of CupCake - but it is hiding almost all of it. How can we make this content show all of it below the CupCake image?
Snapshot of the Toolbar with MahApps.Metro: Only about 10% of the content is showing below the image.
<mah:MetroWindow x:Class="SampleApp.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:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button Click="LaunchGitHubSite" ToolTip="Open up the GitHub site">
<iconPacks:PackIconModern Width="22"
Height="22"
Kind="SocialGithubOctocat" />
</Button>
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<Button Click="DeployCupCakes" Content="Deploy CupCakes">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Width="22"
Height="22"
VerticalAlignment="Center"
Kind="FoodCupcake" />
<TextBlock Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
<Grid>
<!-- Your content -->
</Grid>
</mah:MetroWindow>
First of all, it is better to use a to use a panel that distributes the available space among its content, like a Grid, to prevent cutting off content as with the StackPanel. Here, the data template defines a Grid with two rows, where the TextBlock scales to its desired size and the icon takes up the remaining available space. Also note the HorizontalAlignment of the icon, it is centered.
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<iconPacks:PackIconModern Grid.Row="0"
Width="22"
Height="22"
HorizontalAlignment="Center"
Kind="FoodCupcake" />
<TextBlock Grid.Row="1"
Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
</Grid>
</DataTemplate>
The same result could also be achieved using a DockPanel, where the last child (in this case the icon) takes up the remaining available space, so the order of the defined controls is important.
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom"
Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
<iconPacks:PackIconModern DockPanel.Dock="Top"
Width="22"
Height="22"
HorizontalAlignment="Center"
Kind="FoodCupcake" />
</DockPanel>
</DataTemplate>
In both cases you will get the result below, a button with a centered icon and a text below.
To make the button more prominent, change the title bar height with the TitleBarHeight property.
<mah:MetroWindow x:Class="SampleApp.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:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
TitleBarHeight="50">

WPF Show/Hide a set of controls

I'm working on a WPF desktop application. The MainWindow is a maximized window that has a menu with few menu items. I would like to display few controls within a groupbox on the center of the window. This groupbox contains controls depending on the menu item clicked. So the size of the groupbox should not be static. Is this possible?
Thanks
Try to define your XAML like this
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel>
<Button Content="Click" Height="30" Width="160"/>
<Button Content="Click" Height="30" Width="160"/>
<!--<Button Content="Click" Height="30" Width="160"/>-->
</StackPanel>
</GroupBox>
<Grid Grid.Row="1">
<TextBlock FontSize="26" FontWeight="Bold" HorizontalAlignment="Center" VerticalAlignment="Center" Text="MainUserWork Panel"/>
</Grid>
</Grid>

Resize control based on window width

I have 5 borders inside a stackpanel and each border has a width as Window width/5. When I am maximizing the window then each border width should get resize according to window width/5.
I have tried with converter but it does' not work as how converter will come to know window has resized.
<Window x:Class="ItemPanelTemplateTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Orientation="Horizontal">
<Border Height="20" Background="Red" Width="105" />
<Border Height="20" Background="Green" Width="105" />
<Border Height="20" Background="Yellow" Width="105" />
<Border Height="20" Background="Blue" Width="105" />
<Border Height="20" Background="Orange" Width="105" />
</StackPanel>
</Window>
I don't want to write anything on codebehind as I am using MVVM.
Use different container than StackPanel. The best candidates here are Grid and UniformGrid, but since the latter requires less typing, here it is:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<UniformGrid Height="20" Rows="1">
<Border Background="Red" />
<Border Background="Green" />
<Border Background="Yellow" />
<Border Background="Blue" />
<Border Background="Orange" />
</UniformGrid>
</Window>
The grid will resize automatically with the window and then resize its contents uniformly.

My WPF UserControl must never get wider than the containing ButtonBar

I have bound at top the Width of the UserControl to the Width of the ButtonGrid at top.
It does not work. I want my UserControl always that wide as the width of the ButtonGrid. The problem is loading documents with a long name > Sum(Width of 3 buttons) makes the UserControl as wide as the document name. Now imagine having document names with 100 chars or longer and you add documents the UserContol will bump and jump...
<UserControl x:Class="TBM.View.DocumentListView"
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:Behaviours="clr-namespace:FunctionalFun.UI.Behaviours"
xmlns:Helper="clr-namespace:TBM.Helper"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
Width="{Binding ElementName=ButtonGrid,Path=Width}"
>
<UserControl.Resources>
<Helper:BooleanToVisibilityConverter x:Key="boolToVisibilityConverter" />
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox
SelectionMode="Extended"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
Behaviours:MultiSelectorBehaviours.SynchronizedSelectedItems="{Binding SelectedDocumentViewModelList,Mode=TwoWay}"
Width="Auto"
Focusable="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Name="documentListBox"
BorderThickness="1"
ItemsSource="{Binding DocumentList}"
Visibility="{Binding ElementName=documentListBox,Path=HasItems, Converter={StaticResource boolToVisibilityConverter}}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--<TextBlock Text="{Binding Path=Id}" />-->
<TextBlock Text="{Binding Path=DocumentName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<UniformGrid x:Name="ButtonGrid"
Grid.Row="1"
Rows="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
>
<Button Command="{Binding Path=DeleteDocumentCommand}" HorizontalAlignment="Stretch" Content="Delete" />
<Button Command="{Binding Path=AddDocumentCommand}" HorizontalAlignment="Stretch" Content="Add" />
<Button Command="{Binding Path=OpenDocumentCommand}" HorizontalAlignment="Stretch" Content="Open" />
</UniformGrid>
</Grid>
</UserControl>
You could also set the width of the ParentGrid(containing the control) to a fixed size, en then horizontal alignment to Stretch
Try 2 stuff
Use horizontal alignment on user control to stretch
Set binding to MaxWidth same as Width binding

Resources