Items in ListBox don't stretch properly - wpf

Check this xaml:
<Window
x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Width="300">
<ListBox HorizontalContentAlignment="Stretch"
Grid.IsSharedSizeScope="True">
<ListBox.ItemsSource>
<x:Array Type="{x:Type sys:Int32}">
<sys:Int32>25</sys:Int32>
<sys:Int32>10</sys:Int32>
<sys:Int32>50</sys:Int32>
<sys:Int32>30</sys:Int32>
<sys:Int32>80</sys:Int32>
</x:Array>
</ListBox.ItemsSource>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem"
BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="#FFE41515">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="value"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Value:"/>
<ProgressBar
Value="{Binding Mode=OneWay}"
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
Here's the output, notice that the ProgressBar isn't stretched, why?
If the items are red, it means that each item fills the entire width, then why isn't the ProgressBar stretching??

If you have only SharedSizeGroups the rest space will never be taken, they always behave like Width="Auto" (size to content) with the restriction of the largest item. As you only have two columns you do not even need two such groups as the second will already be the same width in every item, right?
How about this instead:
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" Width="Auto"/>
<ColumnDefinition /> <!-- Implicit: Width="*" -->
</Grid.ColumnDefinitions>

Related

Star sizing Grid columns in an ItemsControl?

I have a ListBox with an ItemsControl bound to a collection in my view model. I'm trying to use star sizing on a grid column within the DataTemplate and set the element within that column (a progress bar) to stretch. This normally would take up all available horizontal space in the grid however nested in an ItemsControl this does not seem to be the case. I've done a bit of reading around & there seems to be known issues using these controls together. Is there a solution to this?
<ListBox>
<ItemsControl ItemsSource="{Binding WebMappingSourcesCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid
ShowGridLines="True"
Grid.IsSharedSizeScope="true"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<CheckBox
Grid.Column="0"
HorizontalAlignment="Center" />
<TextBlock
Grid.Column="1"
Text="{Binding Name}"/>
<ProgressBar Grid.Column="2"
Minimum="0"
Maximum="100"
Value="30"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
MaxHeight="15"
/>
<!-- etc. etc. -->
Try setting HorizontalContentAlignment on your listbox item by giving ItemContainerStyle like below.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>

Wpf datagrid column header as Grid

I have DataGrid with customized column like that
<DataGridTemplateColumn Width="2*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding SomeProperty}"/>
<TextBlock Grid.Column="0" Text="{Binding OtherProperty}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Width="*" Header="Const" Binding="{Binding ConstantValue}" />
As you can see, first column has double width of second column and contains two texblocks. So I need make header consists from two words. Every word above corresponding TexBlock. And I try to use Grid with two columns (because I have textblocks in two columns) as HeaderTemplate. I try to set HeaderStyle like that
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Setters>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
and I try to use HeaderTemplate like that
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
But in both cases I have the same wrong result. Namely. Header1 and Header2 placed togeter without any spaces like Header1Header2. And looks like Header1Header2 has HorizontalAligment="Left" relatively whole header.
I.e.
column border-->|Header1Header2___________|<--column border
So Header1 and Header2 do not placed above corresponding TextBlocks in DataGrid.
How can I solve my problem? How should I set HeaderTemplate to take what I want?
Would customizing the ControlTemplate work for you?
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center">Header1</TextBlock>
<TextBlock Grid.Column="1" HorizontalAlignment="Center">Header2</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</DataGridTemplateColumn.HeaderStyle>
Your other option is to create your own DataGridColumnHeadersPresenter which will hint the available size to the headers. By default, headers' ContentPresenters won't be told the available size and will calculate the width from their content (DataTemplate).
In your case, the width is not set explicitly (e.g. <Grid Width="200">) so it'll simply be the combined size of the TextBoxes.

Issue templating RadioButton in Silverlight 5

I try to apply a really simple ControlTemplate to a RadioButton. But that cause in a weird behavior.
As Long as I´m just clicking the Label everything works fine, but when I click the button control itself it never changes again. Here the complete code of the control:
<UserControl x:Class="RadioButtonDemo.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<ControlTemplate TargetType="RadioButton" x:Key="RadioButtonTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{TemplateBinding Content}"/>
<RadioButton IsChecked="{TemplateBinding IsChecked}" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
<Style TargetType="RadioButton" x:Key="RadioButtonStyle">
<Setter Property="Template" Value="{StaticResource RadioButtonTemplate}"/>
</Style>
</UserControl.Resources>
<StackPanel>
<RadioButton Content="Textbox diabled" GroupName="Group1" Style="{StaticResource RadioButtonStyle}"/>
<RadioButton x:Name="EnabledButton" Content="Textbox enabled" GroupName="Group1" Style="{StaticResource RadioButtonStyle}"/>
<TextBox IsEnabled="{Binding IsChecked, ElementName=EnabledButton}"/>
</StackPanel>
Can someone help?
Please get default style from following link,
http://msdn.microsoft.com/en-us/library/cc296247(v=vs.95).aspx
Use the template by just swapping content and button(:-( code is bulk).

How can a ListBox fill its parent width?

I have a ListBox and need that it fills the parent's width but have not found a way to do it, the ListBox has always the ListBox width and not the 100%.
Here is my XAML code:
<ListBox ItemsSource="{Binding anagSearchResults}" BorderThickness="0" Background="Gray"
SelectedItem="{Binding selectCustomer}"
FontSize="14"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding FirstName}"></TextBlock>
....
What am I doing wrong?
I would check the HorizontalAlignment of the parent(s) and make sure none of them are set to left, right or centre.
I would go with a ListView GridView.
Then for width you need to use a converter.
Change the converter in this sample to be parent width / 4
enter link description here
See the checked answer from me

Applying WPF styles to Child Items

Lets say I have a grid, within my grid I have a number of controls. Instead of setting the margin for each of these controls, I wish to create a style to set the margin for ANY control I drop into a grid. Is this possible?
I was hoping that the following would work:
<Window.Resources>
<Style x:Key="DefaultMargins">
<Setter Property="Control.Margin" Value="3, 3, 3, 3"/>
<Setter Property="Control.FontSize" Value="50"/>
</Style>
</Window.Resources>
<Grid Style="{StaticResource DefaultMargins}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Name="button1">Button</Button>
</Grid>
But the Margin is ignored, it not supporting property value inheritance. Is there a simple alternative to apply the margins to each 'child' of the grid? I understand that it is possible to achieve this sort of thing in CSS and some of our developers are interested in using this sort of construct.
Thanks
Ian
You can specify the style by type and constrain it to the scope of the Grid:
<Grid>
<Grid.Resources>
<Style TargetType="{x:Type Control}">
<Setter Property="Control.Margin" Value="3, 3, 3, 3"/>
<Setter Property="Control.FontSize" Value="50"/>
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Name="button1">Button</Button>
This seems to answer a similar question to yours:
Apply style to all TreeViewItem
If that doesn't work then I'm not too sure about how it would be done in XAML but you could add the style in the code-behind with:
Control element;
for (int i = 0; i < Grid1.Children.Count; i++)
{
element = (Control) Grid1.Children[i];
element.Style = (Style) FindResource("DefaultMargins");
}
Edit: Grid1 refers to a x:Name="Grid1" property added to the XAML grid (poor naming I know).
Place elements inside ItemsControl with ItemsPanel set to Grid and ItemContainerStyle to your style:
<Window.Resources>
<Style x:Key="DefaultMargins">
<Setter Property="Control.Margin"
Value="3, 3, 3, 3" />
<Setter Property="Control.FontSize"
Value="50" />
</Style>
</Window.Resources>
<ItemsControl ItemContainerStyle="{StaticResource DefaultMargins}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="3*" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Button Grid.Row="0"
Grid.Column="0"
Name="button1">Button</Button>
</ItemsControl>
This has a drawback of not working well with designer.

Resources