Margin difference in nested ListBox with DataTemplates - c#

I have a problem with my ListBox. I have written several DataTemplates which I use in a ListBox. Each one of these contains a grid and may contain a nested ListBox depending on the item.
My problem is: The height of these nested ListBoxes seem to be different to the root ListBox's height. Additionally it seems, that there is sometimes one pixel margin to the element above.
Has someone encountered this problem, too and maybe solved it?
XAML-Code:
<!-- Template for SubData-Items -->
<DataTemplate x:Key="DataTemplate">
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999" Background="Violet">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
<Line Grid.ColumnSpan="999" Stroke="Black" X1="0" X2="{Binding ElementName=baseGrid, Path=ActualWidth, Mode=OneWay}" Y1="0" Y2="0" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
<!-- Template for Items -->
<DataTemplate x:Key="GroupDataTemplate">
<Grid Grid.ColumnSpan="999" Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Gantt, Path=GridRowHeight}" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
</Grid>
<Grid x:Name="expandedGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999">
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="0,0,2,0"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
</Grid>
</Grid>
</DataTemplate>
<!-- Grid with ListBox -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="Row0" Height="34"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" Width="25" />
<ColumnDefinition x:Name="Col1" Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999" ItemsSource="{Binding ItemSource, Mode=OneWay}"
ItemTemplate="{StaticResource GroupDataTemplate}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto"
ScrollViewer.CanContentScroll="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
FontSize="10" />
</Grid>

qqbenq gave a very nice solution . Here is another way to do it.
the control templates of ListBox and ListBoxItem has padding inside their borders. Thankfully ListBoxItem border's padding can be control by a style like so:
<Style
TargetType="ListBoxItem">
<Setter
Property="Padding"
Value="0" />
</Style>
but unfortunately for the ListBox , you will have to override the default template with all of its details to change its internal border's hard-coded padding like this:
<Style
TargetType="ListBox">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="0"
SnapsToDevicePixels="true">
<ScrollViewer
Focusable="false"
Padding="{TemplateBinding Padding}">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger
Property="IsEnabled"
Value="false">
<Setter
Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger
Property="IsGrouping"
Value="true">
<Setter
Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
One last note : remove the Margin that you added inside your xaml.
Solution complete

Add a Margin="-2,0,0,0" and a Padding="-1" to your "LBMaGruppen" named ListBox.
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="-2,0,0,0" Padding="-1"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
Also, the "root" element's height is binded to {Binding ElementName=Gantt, Path=GridRowHeight}, while the "sub" element's height to {Binding ElementName=Row0, Path=Height}, so this must cause the difference.

It seems that you have auto height set on all your ListBox. You could try setting the height to a specific size. EDIT: I see you already have ScrollViewer settings. I think setting the height of the box to a specific size instead of auto will do what you want.
As to the padding between elements see the ListBox.ItemContainerSyle which should allow you to set the margin between elements.

Related

Border is added only to the first text block in WPF

Edit : I realized what the problem is, when I add the border, The second TextBlock sits on top of the first TextBlock. Still have to figure out why this is happening.
Original question:
I have a number of TextBlocks in my xaml. I want to add a border around some textblocks. I tried the following methods.
Method 1:
<Style x:Key="BorderForTextBlock" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
<TextBlock1../>
<Border Style="{StaticResource BorderForTextBlock}">
<TextBlock2.../>
</Border>
Method 2:
<TextBlock1../> //This is where the border is added.
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock2 ..../> //This is where I want to add the border
</Border>
A border is added only to the first TextBlock in the xaml no matter to which TextBlock I add the border. I don't want the border on the first TextBlock. I have no clue why this is happening.
This is my xaml :
<Grid Background="LightYellow" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" ></ColumnDefinition>
<ColumnDefinition Width="3.5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28*" ></RowDefinition>
<RowDefinition Height="120*" ></RowDefinition>
<RowDefinition Height="28*"></RowDefinition>
<RowDefinition Height="74*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source1"/>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
</Border>
<TextBlock Grid.Row="1" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source2}"/>
<RichTextBox Background="LightYellow" Margin="0,0,0,0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" Grid.Row="1" Grid.Column="1" IsReadOnly="True" >
<FlowDocument>
<Paragraph>
<Run Text="{Binding content2, Mode=TwoWay}"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<TextBlock Grid.Row="2" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source3"/>
<TextBlock Text="{Binding content3, Mode=TwoWay}" Margin="0,0,0,0" Grid.Row="2" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" TextWrapping="Wrap"/>
<TextBlock Grid.Row="3" Margin="10,0,5,0" FontWeight="SemiBold" Text="{x:Static res:Resources.source4}"/>
<TextBox Text="{Binding content4, Mode=TwoWay}" Margin="0,0,0,0" Grid.Row="3" Grid.Column="1" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True" TextAlignment="Left" TextWrapping="Wrap" Background="LightYellow" IsReadOnly="True"/>
</Grid>
instead of
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
</Border>
Have
<Border Grid.Row="0" Grid.Column="1" BorderBrush="Black" BorderThickness="1">
<TextBlock x:Name="txtBlock1" FormatTest:FormattedTextBehavior.FormattedText="{Binding Path= content1}" Margin="0,0,0,0" TextWrapping="Wrap"/>
</Border>
This should solve the issue with placement of text blocks
This is how it looks at my end
Try this and let us know
You can use style with trigger and put the style either in windows resources or app resources depending upon scope you want
<Window x:Class="WpfApplication2.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">
<Grid>
<Grid.Resources>
<Style x:Key="NotCalledBorder" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="Height" Value="20"/>
<Setter Property="Width" Value="30"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Style="{StaticResource NotCalledBorder}" Grid.Row="0">
<TextBlock Text="test1" Grid.Row="0" OpacityMask="Black">
</TextBlock>
</Border>
<TextBlock Text="test2" Grid.Row="1"></TextBlock>
<Border Style="{StaticResource NotCalledBorder}" Grid.Row="2">
<TextBlock Text="test3" Grid.Row="2" OpacityMask="Black"></TextBlock>
</Border>
<TextBlock Text="test4" Grid.Row="3"></TextBlock>
</Grid>
</Window>
Conditional style in WPF. Adding border to two textblocks only. You can apply style and add to as many as you want

3x3 Grid containing a Path in the center fills the entire grid

I have the following ControlTemplate that I am using in an ItemsControl. It is essentially a 3x3 Grid with a Path in the center and a Textbox/Textblock on top of it. When I use this, the Path takes up all of the space within the ItemsControl, and ignores the column/row definition constraints. Can anyone tell me why this is happening? I tried wrapping the Path in a Canvas but that didn't seem to help.
Thanks!
<controls:Toolbox x:Key="DrawingShapeTemplates"
DefaultItemSize="60, 60"
SnapsToDevicePixels="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ItemsControl.Items>
<Path Style="{StaticResource Square}"
ToolTip="Square Shape">
<controls:DesignerItem.MoveThumbTemplate>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1">
<TextBlock Text="Length" />
<TextBox MinWidth="{Binding RelativeSource={RelativeSource AncestorType=controls:DesignerItem}, Path=ActualWidth}" />
</StackPanel>
<Canvas Grid.Column="1"
Grid.Row="1">
<Path Style="{StaticResource Square_DragThumb}" />
</Canvas>
</Grid>
</ControlTemplate>
</controls:DesignerItem.MoveThumbTemplate>
</Path>
</ItemsControl.Items>
</controls:Toolbox>
The Style.
<Style x:Key="Square"
TargetType="Path"
BasedOn="{StaticResource StandardShapeStyle}">
<Setter Property="Data">
<Setter.Value>
<RectangleGeometry Rect="50 50 50 50" />
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Square_DragThumb"
TargetType="Path"
BasedOn="{StaticResource Square}">
<Setter Property="IsHitTestVisible"
Value="True" />
<Setter Property="Fill"
Value="Transparent" />
<Setter Property="Stroke"
Value="Transparent" />
</Style>
Edit
The source for this was downloaded from hereenter link description here. If you replace the <Path Style="{StaticResource Decision}" at line 469 with the following, you will get the same result that I do.
<Path Style="{StaticResource Decision}"
ToolTip="Decision">
<s:DesignerItem.MoveThumbTemplate>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="3*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1">
<TextBlock Text="Length" />
<TextBox MinWidth="{Binding RelativeSource={RelativeSource AncestorType=s:DesignerItem}, Path=ActualWidth}" />
</StackPanel>
<Path Grid.Column="1"
Grid.Row="1"
Style="{StaticResource Decision_DragThumb}" />
</Grid>
</ControlTemplate>
</s:DesignerItem.MoveThumbTemplate>
</Path>
The following are pictures of what I am trying to accomplish and what the actual result is. I want to display a label and a text box on all four sides of the selected item when it is selected. Ultimately the label/textbox visibility will be databound to the DesignerItem.IsSelected dependency property, but that hasn't been wired up yet.
Expected result:
Actual result:
Typically Canvas do to clip it's children by default so you need to set it explicitly as ClipToBounds="True"
eg
<Canvas Grid.Column="1"
Grid.Row="1"
ClipToBounds="True">
<Path Style="{StaticResource Square_DragThumb}" />
</Canvas>
Update
Replace the Path element in FlowChartSymbols.xaml at line 469 with the following Grid
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Column="1">
<TextBlock Text="Length" HorizontalAlignment="Center"/>
<TextBox />
<StackPanel.Style>
<Style TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=s:DesignerItem}}"
Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
<Path Style="{StaticResource Decision}"
Grid.Row="1" Grid.Column="1"
ToolTip="Decision">
<s:DesignerItem.MoveThumbTemplate>
<ControlTemplate>
<Path Style="{StaticResource Decision_DragThumb}" />
</ControlTemplate>
</s:DesignerItem.MoveThumbTemplate>
</Path>
</Grid>
this is how you can achieve the same. also fixed toolbox issue by adding a trigger to detect if it is inside a designer item or simply in a toolbox

XAML Listbox alignment issue

I have a Windows Phone 8 page with Country Names on left and ISD codes on right. I want to align the country name to the extreme left and ISD code to the extreme right of the screen.
For this, I wrote the following XAML
<Grid x:Name="LayoutRoot" Background="Transparent">
<ListBox ItemsSource="{Binding IsdCodes}" HorizontalAlignment="Stretch" Background="Blue">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Background="Yellow" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Text="{Binding Key}" />
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
But the output I am getting is as follows :
As I gave the grid column widths as 3* and *, I expected first column to occupy 75% of the width of the screen on left and 2nd column to occupy 25% of the width of the screen on the right. But I do see that listbox item still doesn't occupy the entire screen width (Assumed from the yellow background).
Where did I go wrong?
Try setting HorizontalContentAlignment for ListBoxItem to Stretch:
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
This is because the DataTemplate is rendered in a ContentPresenter, which is not stretched in the ListBoxItem. You need to redefine the template for the ListBoxItem:
...
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
<ContentPresenter HorizontalAlignment="Stretch" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
...
As you know width of screen is 480 you could assign it 360 and 120
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Background="Yellow" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="360"/>
<ColumnDefinition Width="120" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Text="{Binding Key}" />
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
This would help you, set width of grid inside listbox datatemplete
<Grid x:Name="LayoutRoot" Background="Transparent">
<ListBox ItemsSource="{Binding IsdCodes}" HorizontalAlignment="Stretch" Background="Blue">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Background="Yellow" ShowGridLines="True" Width="460">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" HorizontalAlignment="Stretch" Text="{Binding Key}" />
<TextBox Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

How to Change Pivot Header Template in Windows Phone 8

I would like to be able to change the background of the Pivot Headers and Application Title in Windows Phone 8. From what I gather, I must create a custom style targeting the Pivot control. I am not sure, however, to change the background of only the headers?
I would like to adjust the style somehow
<Style x:Key="MyPivotStyle" TargetType="phone:Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid CacheMode="BitmapCache" Grid.RowSpan="2">
<Grid.Background>
<ImageBrush ImageSource="/Assets/bg_header.png"/>
</Grid.Background>
</Grid>
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache" Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}" Margin="24,17,0,-7">
<StackPanel Orientation="Horizontal">
<Image Source="/Assets/company_name.png" Width="213.75" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Button HorizontalAlignment="Right" VerticalAlignment="Top" Margin="140,-20,0,35" BorderThickness="0" x:Name="btnHome">
<Image Source="/Assets/btnHome.png" Width="48" Height="48" ></Image>
</Button>
</StackPanel>
</ContentPresenter>
<controlsPrimitives:PivotHeadersControl x:Name="HeadersListElement" Foreground="White" Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter" Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
EDITED for WinRT (sorry for the delay and thanks for the reminder to update this answer):
To edit a full template right click on the control when in Document Outline and select Edit Template - Current (in Visual Studio or Blend) and the template will be generated for you and you can edit as you want, see my answer here for screenshots.
Here are the two examples below (posted in 2013) redone for Windows Phone Windows Runtime:
<Grid Background="Transparent">
<Pivot Title="Re-templating example">
<Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Blue">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.TitleTemplate>
<DataTemplate>
<Grid Background="Green">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</Pivot.TitleTemplate>
<PivotItem Header="One">
<TextBlock FontSize="35"
Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35"
Text="This is item 2" />
</PivotItem>
</Pivot>
</Grid>
And second example, notice that we are wrapping the ContentPresenter in a Grid (you could use a border as well or any other element):
<Page.Resources>
<SolidColorBrush x:Key="PivotBackground" Color="#FFE46C08"/>
<Style x:Key="PivotStyle" TargetType="Pivot">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Pivot">
<Grid x:Name="RootElement" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Notice that ContentControl is wrapped in a Grid and Background set to resource furtehr up-->
<Grid VerticalAlignment="Center" Background="{StaticResource PivotBackground}">
<ContentControl x:Name="TitleContentControl" ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" Style="{StaticResource PivotTitleContentControlStyle}"/>
</Grid>
<ScrollViewer x:Name="ScrollViewer" HorizontalSnapPointsAlignment="Center" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="Hidden" Margin="{TemplateBinding Padding}" Grid.Row="1" Template="{StaticResource ScrollViewerScrollBarlessTemplate}" VerticalSnapPointsType="None" VerticalScrollBarVisibility="Disabled" VerticalScrollMode="Disabled" VerticalContentAlignment="Stretch" ZoomMode="Disabled">
<PivotPanel x:Name="Panel" VerticalAlignment="Stretch">
<!--Background set to resource further up-->
<PivotHeaderPanel Background="{StaticResource PivotBackground}" x:Name="Header" >
<PivotHeaderPanel.RenderTransform>
<CompositeTransform x:Name="HeaderTranslateTransform" TranslateX="0"/>
</PivotHeaderPanel.RenderTransform>
</PivotHeaderPanel>
<ItemsPresenter x:Name="PivotItemPresenter">
<ItemsPresenter.RenderTransform>
<TranslateTransform x:Name="ItemsPresenterTranslateTransform" X="0"/>
</ItemsPresenter.RenderTransform>
</ItemsPresenter>
</PivotPanel>
</ScrollViewer>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Using the above style:
<Grid Background="Transparent">
<Pivot Style="{StaticResource PivotStyle}"
Title="Re-templating example">
<PivotItem Header="One">
<TextBlock FontSize="35" Text="This is item one" />
</PivotItem>
<PivotItem Header="Two">
<TextBlock FontSize="35" Text="This is item 2"/>
</PivotItem>
</Pivot>
</Grid>
By the way, it's usually preferred to keep styles in a separate style file- I've only kept them on the same page for simplicity for this example. If you remove the x:key attribute the style will be applied to all the controls of the set target type (Pivot in this example).
Answer from 2013 for Windows Phone 7.X and Windows Phone 8 (WP Silverlight:
There are a few ways you can do it, but here is one example:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<phone:Pivot Grid.Row="1">
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<Grid Background="Red" Height="200">
<TextBlock Text="{Binding}"/>
</Grid>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
<phone:PivotItem Header="Test">
<TextBlock Text="ghjgb"/>
</phone:PivotItem>
</phone:Pivot>
If you however want to do this:
You can do this, remove the x:key to apply to all pivoits, or use the key to set the style on just selected pivoit elements like so:
<controls:Pivot Title="The Marathon Runner" Style="{StaticResource PivotStyle}">
<Style x:Key="PivotStyle" TargetType="phone:Pivot">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Background="#ff9000" CacheMode="BitmapCache" Grid.RowSpan="2" />
<Grid Background="{TemplateBinding Background}" CacheMode="BitmapCache"
Grid.Row="2" />
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}"
Content="{TemplateBinding Title}" Margin="24,17,0,-7"/>
<Primitives:PivotHeadersControl x:Name="HeadersListElement"
Grid.Row="1"/>
<ItemsPresenter x:Name="PivotItemPresenter"
Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Dont forget to use:
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:Primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone"

C#, WPF, Autorezise Listbox when window resize

C#, Visual Studio 2010, dot net 4, WPF, Microsoft Ribbon
I have a WPF window with the ribbon menues at the top of the window and an area below
where I try to fill with my controls however I can not get the controls to rezise with
my window.
The listbox in the below example should be fully "expanded" witin its boundaries when the window appear and its width should follow the window width when the user resize the window
(the user should not resize the controls itself) by dragging i nthe windows sides.
I tried a lot of playing around with the controls and searched the web but have not been able to
find a solution (some site indicated the usage of border would do the trick).
The Image image1 is a background image spanning over the whole "surface".
The Image image2 is a small logo picture.
<DockPanel DockPanel.Dock="Top">
<Grid DockPanel.Dock="Top" Height="526" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Name="BaseGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1" />
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" HorizontalAlignment="Left" Name="image1" VerticalAlignment="Top" Source="........./el_bg.jpg" Stretch="None" />
<Grid Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Margin="2" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="........./shiny_rgb.png" />
<ListBox Grid.Column="2" Grid.Row="0" Name="MessageToUser" VerticalAlignment="Top" />
</Grid>
</Grid>
</DockPanel>
Regards
You're setting horizontal alignments to Left that shouldn't be set. Try this:
<DockPanel DockPanel.Dock="Top">
<Grid DockPanel.Dock="Top" Height="526" VerticalAlignment="Top" Margin="2" Name="BaseGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1" />
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" HorizontalAlignment="Left" Name="image1" VerticalAlignment="Top" Source="........./el_bg.jpg" Stretch="None" />
<Grid Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="........./shiny_rgb.png" />
<ListBox Grid.Column="2" Grid.Row="0" Name="MessageToUser" VerticalAlignment="Top">
<ListBoxItem>One</ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
</ListBox>
</Grid>
</Grid>
</DockPanel>
In addition, your ListBox is in the third column of its containing Grid. If you want it to stretch across the entire window, you will need to ensure it spans all three columns:
<ListBox Grid.ColumnSpan="3" Grid.Row="0" Name="MessageToUser"
VerticalAlignment="Top">
You should read up on WPF layout - you're setting way more properties here than you need to be. Once you understand it, you'll find this thing much more intuitive. In addition, you can use a tool like Snoop to help figure out what is wrong with your layout.
Applying the following style helped me meet this requirement:
<Style x:Key="listBoxAutoFill" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My requirement is more about resizing the listbox height as the window grows/shrinks but the same can be applied for width.
<ListBox Grid.Row="1" Grid.Column="0" Width="158"
ItemContainerStyle="{StaticResource listBoxAutoFill}"
ItemsSource="{Binding ListBoxItems, Mode=TwoWay}" />

Categories