Odd WPF Grid Behavior Affected by TextBox Text - wpf

I can't figure out why the contents of my TextBox is affecting my grid column widths. I have setup a grid with 3 columns with widths defined as 50, *, 50, as shown below
Now, when in use, the center column will grow/shrink as the text in the TextBox changes, see the 2 examples below. The actual TextBox is not changing size, so I can't understand why in the world the grid is changing. The Grid is inside of a Border inside a UserControl. The UserControl is used as a DataTemplate in a ListBox.
Edit: I've discovered that this issue is related to the UserControl being in a ListBox, see example image below (UserControl in ListBox (circled in red) vs. UserControl Placed on Form (circed in blue). The grid behaves as expected when the UserControl is placed directly on the form. Code for the form is given below.
UserControl XAML:
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="Name:" Margin="2" />
<TextBox Grid.Column="1" Margin="2" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2" />
<TextBlock Text="Shift:" Grid.Row="1" Margin="2" />
<TextBox Grid.Column="1" Grid.Row="1" Margin="2" Text="{Binding TimeShift, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, FallbackValue=0}" HorizontalContentAlignment="Right" />
<TextBlock Text="s" Grid.Row="1" Grid.Column="2" Margin="2" />
</Grid>
Window/Form XAML:
<Window x:Class="CrashSimOffice.FileImport"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CrashSimOffice"
Title="File Import" Height="350" Width="450" Background="White" Icon="/CrashSimOffice;component/Images/16/page-white-save.png">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="75"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Content="Add" Margin="2" Command="{Binding AddFileCommand}" />
<Button Content="Remove" Grid.Column="1" Margin="2" Command="{Binding RemoveFileCommand}" />
<ListBox HorizontalContentAlignment="Stretch" Grid.ColumnSpan="4" Margin="2" Grid.Row="1" ItemsSource="{Binding Files}" SelectedItem="{Binding CurrentFile}" ScrollViewer.CanContentScroll="False" Background="WhiteSmoke">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:FileViewModel}">
<local:FileView DataContext="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Done" Grid.Column="3" Margin="2" Grid.Row="2" Click="Button_Click" />
<local:FileView Grid.Row="3" Grid.ColumnSpan="4" />
</Grid>

OK, I figured it out, Bruno V you got me thinking it must have something to do with the ListBox. I needed to add this to my ListBox:
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Not sure why that works, but it does.

Related

How resize whole window when I drag window with mouse

I'm new with WPF controls, before I worked with WinForms applications, and there if I put anchor on control and put dock on container all works smoothly but here I have struggle where I mistake?
<Window x:Class="ChatApp.Client.ClientWindow"
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:ChatApp.Client"
mc:Ignorable="d"
Title="Client" Height="450" Width="800">
<Grid>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<GroupBox Header="Client" Height="Auto">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="5, 0, 5, 0">Address:</TextBlock>
<TextBox x:Name="txtAddress" Width="80"></TextBox>
<TextBlock Margin="10, 0, 5, 0">Port:</TextBlock>
<TextBox x:Name="txtPort" Width="80"></TextBox>
<Button x:Name="btnConnect" Margin="430, 0, 5, 0" Content="Connect" Width="80" Click="btnConnect_Click"/>
</StackPanel>
</GroupBox>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<GroupBox Header="Chat" Width="650" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBox x:Name="txtConversation" AcceptsReturn="True"></TextBox>
</GroupBox>
</StackPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<GroupBox Header="Users" Width="135" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ListBox x:Name="lbUsers" Height="Auto" Margin="5,0" VerticalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</GroupBox>
</StackPanel>
</DockPanel>
</Grid>
</Window>
I have three group box top dock, second left dock and last one is for right dock.
When I want to resize form with mouse right group box doesn't want to stretch when
I resize form.
Your layout seems very over complicated - are you just trying to clone what you did in Winforms in WPF?
It doesn't make any sense to have StackPanels or a Grid with only one child control each.
Try replacing your DockPanel with appropriately sized Grid Rows and Columns.
The GroupBoxes won't resize if you hard code their widths.
There's no need to define an ItemTemplate for the ListBox just to display a single string.
Something like the following would be a good starting point for your layout.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="*" MinWidth="135" />
</Grid.ColumnDefinitions>
<GroupBox Header="Client" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="5">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Address:"/>
<TextBox x:Name="txtAddress" Width="80" Grid.Row="1" Grid.Column="0" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Port:" />
<TextBox x:Name="txtPort" Width="80" Grid.Row="3" Grid.Column="0" />
<Button x:Name="btnConnect" Grid.Row="0" Grid.Column="2" Content="Connect" Width="80" />
</Grid>
</GroupBox>
<GroupBox Header="Chat" Grid.Row="1" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBox x:Name="txtConversation" AcceptsReturn="True" />
</GroupBox>
<GroupBox Header="Users" Grid.Row="1" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ListBox x:Name="lbUsers" />
</GroupBox>
</Grid>

Grid rows aren't the (relative) height I set them to

I was working on a UserControl in a View, when I came across this problem:
I set my content grids row heights to be 2*, 1* and 1* with the lines in between set to auto.
Now. The uppermost row has a grid nested in with a TextBlock and a TextBox. The height of the cell is in no way 2*. It looks like it would look if I had set it to auto. I'm pretty sure the other 2 content rows (containing buttons) are the right height either.
Now I hope you guys can help me fix this. I've googled around a bit and I can't seem to find a fitting solution.
Here's the code:
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="TBCustomerTitle" Margin="0,0,8,0" FontWeight="Bold"
Visibility="{Binding SetVisibility, UpdateSourceTrigger=PropertyChanged}">Customer:</TextBlock>
<TextBox Name="TBCustomerData" Grid.Column="1"
Visibility="{Binding SetVisibility, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding DisplayedCustomer.Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
<Line Grid.Row="1" Style="{StaticResource horizontalLineStyle}" />
<StackPanel Grid.Row="2" Orientation="Vertical">
<Button Command="{Binding AddCommand}">Add a new customer</Button>
<Button Command="{Binding UpdateCommand}">Update the selected customer</Button>
<Button Command="{Binding DeleteCommand}">Delete the selected customer</Button>
</StackPanel>
<Line Grid.Row="3" Style="{StaticResource horizontalLineStyle}" />
<StackPanel Grid.Row="4" Orientation="Vertical">
<Button Command="{Binding RefreshCommand}">Refresh the list</Button>
<Button Command="{Binding ClearSelectionCommand}">Clear selection</Button>
</StackPanel>
</Grid>
EDIT: Now with screenshot, as requested. It's the right column I'm talking about (So yes, this UserControl is in itself another nested Grid)
EDIT 2: Here's the containing code. My page consist of three classess.
The 1st (ApplicationView.xaml) is a Window. It has the navigation buttons in the left column, a nice line, and one column containing the view of that specific object. It has no rows.
ApplicationView.xaml
<Grid>
<Grid.Resources>
<ResourceDictionary Source="StylesRD.xaml" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="6*" />
</Grid.ColumnDefinitions>
<!-- A DockPanel for the Navigation Buttons-->
<DockPanel Grid.Column="0" Margin="0,20" VerticalAlignment="Top" HorizontalAlignment="Center">
<ItemsControl ItemsSource="{Binding PageViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}"
Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding }"
Margin="2,5"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
<Line Grid.Column="1" Style="{StaticResource verticalLineStyle}" />
<ContentControl Grid.Column="2" Content="{Binding CurrentPageViewModel}" />
</Grid>
The view (CustomerView.xaml) is the 2nd file. It is a User control and it also has 3 columns, one with the list of Customers in this case, one for the beautiful seperating line (it is beautiful, right? /sarcasm) and the one I'm struggling with right now with the details and the buttons to do stuff.
Here also no rows.
CustomerView.xaml
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!-- Customer list -->
<view:CustomerListView Grid.Column="0" VerticalAlignment="Top"/>
<Line Grid.Column="1" Style="{StaticResource verticalLineStyle}" />
<!-- Details -->
<view:CustomerDetailsView Grid.Column="2" VerticalAlignment="Top"/>
</Grid>
Your inner Grid has two RowDefinitions without a height setting. Therefore the default Height="*" will be used for both rows. Your inner grid doesn't need two RowDefinitions, so removing them should fix your issue. So your inner grid definition should look like this:
<Grid>
<!--
remove these row definitions
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="TBCustomerTitle" Margin="0,0,8,0" FontWeight="Bold"
Visibility="{Binding SetVisibility, UpdateSourceTrigger=PropertyChanged}">Customer:</TextBlock>
<TextBox Name="TBCustomerData" Grid.Column="1"
Visibility="{Binding SetVisibility, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding DisplayedCustomer.Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
Edit:
It works for me as expected. The TextBox and TextBlock get stretched to 2* height, and the two StackPanels have a height of 1* each. Please provide the XAML where you use your user control. Seems like there lies the problem.
Edit 2:
Ah, now I see it. The VerticalAlignment="Top" setting in your CustomerView.xaml pushes your CustomerDetailsView to the top. Either remove this attribute or set the VerticalAlignment to Stretch.
The xaml you provided is working fine, the problem is in the containing xaml. Look at this example xaml.
<StackPanel Orientation="Horizontal">
<Border Background="Yellow">
<local:MyUserControl/>
</Border>
<StackPanel Background="Green">
<local:MyUserControl/>
</StackPanel>
</StackPanel>
And the usercontrol (stripped away bindings and styles)
<UserControl x:Class="WpfApplication3.MyUserControl"
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:WpfApplication3"
mc:Ignorable="d">
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="TBCustomerTitle" Margin="0,0,8,0" FontWeight="Bold" >Customer:</TextBlock>
<TextBox Name="TBCustomerData" Grid.Column="1" Text="{Binding DisplayedCustomer.Name, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
<Line Grid.Row="1" Height="5"/>
<StackPanel Grid.Row="2" Orientation="Vertical">
<Button Command="{Binding AddCommand}">Add a new customer</Button>
<Button Command="{Binding UpdateCommand}">Update the selected customer</Button>
<Button Command="{Binding DeleteCommand}">Delete the selected customer</Button>
</StackPanel>
<Line Grid.Row="3" Height="5"/>
<StackPanel Grid.Row="4" Orientation="Vertical">
<Button Command="{Binding RefreshCommand}">Refresh the list</Button>
<Button Command="{Binding ClearSelectionCommand}">Clear selection</Button>
</StackPanel>
</Grid>
</UserControl>
As you can see the usercontrol located in the stackpanel is not stretching because stackpanel does not stretch it's contents.

WPF DataGrid not showing scrollbars and running out of visible area

Like others I have a DataGrid that is not showing scrollbars. What I think is unique to my situation is that I do not see a StackPanel anywhere in the visual or logical tree. I am using WPF Inspector to view the trees. I have tried various suggestions to set the height and width of the containing Grid columns and rows with no success. I'm certain there is something I'm missing that is allowing the content to extend beyond the visible area but I cannot tell what it is yet. Any help would be appreciated. This application is a WPF Prism with MEF app and the DataGrid is within a UserControl which is in a Prism region.
Shell Window XAML:
<Window>
<Grid x:Name="GridOuterShell">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ribbon:Ribbon Grid.Row="0" >
...
</ribbon:Ribbon>
<Grid x:Name="GridShellContent" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="350" MinWidth="300"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<local:RegionBorderControl Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Margin="2,2,8,2" RegionName="{Binding MainRegionDisplayName}"
Style="{DynamicResource RegionBorderControlStyle}">
<ContentControl prism:RegionManager.RegionName="MainRegion"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"/>
</local:RegionBorderControl>
<GridSplitter Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" HorizontalAlignment="Center" VerticalAlignment="Stretch"
Width="3" ShowsPreview="True" ResizeDirection="Columns" />
<local:RegionBorderControl Grid.Row="0" Grid.Column="2" RegionName="{Binding RightTopRegionDisplayName}"
Style="{DynamicResource RegionBorderControlStyle}">
<ContentControl prism:RegionManager.RegionName="RightTopRegion"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"/>
</local:RegionBorderControl>
<GridSplitter Grid.Row="1" Grid.Column="3" HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="3" ShowsPreview="true" ResizeDirection="Rows" ResizeBehavior="PreviousAndNext" Background="Silver"/>
<local:RegionBorderControl Grid.Row="2" Grid.Column="2" RegionName="{Binding RightBottomRegionDisplayName}"
Style="{DynamicResource RegionBorderControlStyle}">
<ContentControl prism:RegionManager.RegionName="RightBottomRegion"/>
</local:RegionBorderControl>
</Grid>
<StatusBar Grid.Row="2">
...
</StatusBar>
</Grid>
</Window>
UserControl XAML:
<UserControl>
<Grid x:Name="GridMain">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" LastChildFill="False" HorizontalAlignment="Stretch" Width="Auto" >
<ToolBar x:Name="tbToolBar" DockPanel.Dock="Left" Background="{x:Null}">
...
</ToolBar>
</DockPanel>
<DataGrid AutoGenerateColumns="False" Grid.Row="2" Name="DataGridList" ItemsSource="{Binding MyItems}" IsReadOnly="True" CanUserResizeRows="False" SelectionMode="Single"
SelectedItem="{Binding Path=SelectedDataGridRecord, Mode=TwoWay}" Style="{StaticResource DataGridDefault}" >
<DataGrid.Columns>
...
</DataGrid.Columns>
</DataGrid>
</Grid>
You have the DataGrid in a Grid row where the RowDefinition Height is auto so the grid will be measured with an infinite height and be arranged to its DesiredSize.Height and never show scrollbars. Seems like the grid should be in row 1 or make the height of row 2 to be * instead of auto.

How to add new elements to the base Grid from an inherited DataTemplate?

I have two objects: Bicycle and BicycleFullSuspension, which inherits Bicycle and contains additional properties (strings and decimals). I managed to make a functioning DataTemplateSelector that will choose either my LbxItemTemplateBicycle DataTemplate or my LbxItemTemplateFullSuspension DataTemplate, depending on to which class the object in an ObservableCollection belongs. Both of these templates are bound to the parent template ListBoxItemTemplate.
I am trying to display information about each object in a ListBox, and each of the inheriting templates should add a few more fields to the grid in the parent DataTemplate. My problem is that I cannot figure out how to add WPF elements to the grid in ListBoxItemTemplate from one of the inherited templates. I cannot assign a key to the grid in the template, so I am not sure how to specify that additional TextBlocks should end up in the same grid that is in the parent template. (Right now, additional TextBlocks are stacked on top of the parent grid.)
<DataTemplate x:Key="ListBoxItemTemplate">
<Border Name="LbxItemTemplate" BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5">
<Grid>
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
...
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Bike Year:" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding BikeYear}" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Bike Color: "/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding BikeColor}"/>
...
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="LbxItemTemplateFullSuspension" DataType="{x:Type app:BicycleFullSuspension}">
<Grid>
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
<TextBlock Grid.Row="6" Grid.Column="0" Text="Shock Travel"/>
<TextBlock Grid.Row="6" Grid.Column="1" Text="{Binding ShockTravel}"/>
</Grid>
</DataTemplate>
I found these links helpful for getting to this point:
http://dariosantarelli.wordpress.com/2011/07/28/wpf-inheritance-and-datatemplates/
http://zamjad.wordpress.com/2009/12/31/applying-data-template-conditionally/
Is there a way to use data-template inheritance in WPF?
Edit:
I'm not sure why I didn't think to put the Border on the template inheriting the base, but by nesting a StackPanel inside of the Border in the inheriting template (StackPanel contains the ContentPresenter with the base template content along with the Grid that has the added information), everything lines up very nicely:
Working solution, using input from XAMeLi:
<DataTemplate x:Key="ListBoxItemTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" SharedSizeGroup="LabelColumnGroup" />
<ColumnDefinition Width="150" SharedSizeGroup="LabelColumnGroup" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Bike Year:" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding BikeYear}" />
...
</Grid>
</DataTemplate>
<DataTemplate x:Key="LbxItemTemplateFullSuspension" DataType="{x:Type app:BicycleFullSuspension}" >
<Border BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5" Grid.IsSharedSizeScope="True" Width="500">
<StackPanel>
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumnGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumnGroup" />
</Grid.ColumnDefinitions>
...
<TextBlock Grid.Row="7" Grid.Column="0" Text="Shock Type: "/>
<TextBlock Grid.Row="7" Grid.Column="1" Text="{Binding ShockType}"/>
...
</Grid>
</StackPanel>
</Border>
</DataTemplate>
You cannot add UIElemets to a data template, but you can layout the bigger template to look like it has added text to the base template.
Basically, you are on the right path, only the layout of the big template is corrupt. (Too bad you omitted the structure of your rows and columns)
Try this:
<DataTemplate x:Key="ListBoxItemTemplate">
<Border Name="LbxItemTemplate" BorderBrush="DarkRed" BorderThickness="2" Padding="5" Margin="5">
<Grid>
<Grid.RowDefinitions>
...
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="LabelGroupColumn"/>
...
</Grid.ColumnDefinitions>
....
</Border>
</DataTemplate>
<DataTemplate x:Key="LbxItemTemplateFullSuspension">
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/><!--This will hold the default template-->
<!--From here define the same structure as in the default template, if you have rows for margins and such-->
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
SharedSizeGroup="LabelGroupColumn"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource ListBoxItemTemplate}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Shock Travel"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ShockTravel}"/>
</Grid>
</DataTemplate>
It seems that your grids have Label-Value structures and you want all the values to start from the same vertical line (this is very good from UX point of view). Notice the SharedSizeGroup setters on column definitions and the Grid.IsSharedSizeScope="True" on a mutual parent. This will keep the width of the label column to be synchronized among the grids.

WPF - Usercontrol height does not size properly

I have an issue I cannot figure out. I hope I can explain things enough.
Basically, I have a usercontrol that I'm looking to use as a sort of in window modal dialog.
<Grid>
<Rectangle Opacity=".75" Fill="White"/>
<Border Width="425" BorderBrush="LightGray" BorderThickness="2" CornerRadius="20,0,20,0" Padding="3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="15"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- First Name -->
<Label Grid.Row="0" Grid.Column="0" Content="First Name:"/>
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding FirstName}" Margin="3"/>
<!-- Last Name -->
<Label Grid.Row="0" Grid.Column="3" Content="Last Name:"/>
<TextBox Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="2" Text="{Binding LastName}" Margin="3"/>
<!-- Address -->
<Label Grid.Row="1" Grid.Column="0" Content="Address:"/>
<TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" Text="{Binding Address}" HorizontalAlignment="Stretch" Margin="3"/>
<!-- City -->
<Label Grid.Row="2" Grid.Column="0" Content="City:"/>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding City}" Margin="3"/>
<!-- State -->
<Label Grid.Row="2" Grid.Column="2" Content="State:"/>
<ComboBox Grid.Row="2" Grid.Column="3" ItemsSource="{Binding States}" SelectedValue="{Binding State}" Margin="3"/>
<!-- Zip Code -->
<Label Grid.Row="2" Grid.Column="4" Content="Zip Code:"/>
<TextBox Grid.Row="2" Grid.Column="5" Text="{Binding ZipCode}" Margin="3"/>
<Button Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="6" Width="100" HorizontalAlignment="Center" Content="Save" Command="{Binding SaveCustomerCommand}"/>
</Grid>
</Border>
</Grid>
I also have a resourcedictionary containing a datatemplate to connect this usercontrol to it's viewmodel.
<DataTemplate DataType="{x:Type vm:CreateCustomerViewModel}">
<view:CreateCustomerView/>
</DataTemplate>
Finally, in the main window viewmodel, I create an instance of the control's viewmodel, and in the main window view, I am using an itemscontrol and binding it's itemssource property to the instance of the control's viewmodel.
<ItemsControl Height="600" Grid.Row="0" ItemsSource="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
Now, my issue is using the itemscontrol in the main window, I've tried a few different ways, but I cannot get the control to be the height of the window. I'm not sure if I shouldn't be using an itemscontrol, or what I'm doing wrong. Any help is very much appreciated.
ItemsControl is for collections. By default it uses a StackPanel to contain its child elements, which disallows stretching in the stack direction (Vertical by default). For a single item use ContentControl (the base of things like Button and Label) instead:
<ContentControl Height="600" Grid.Row="0" Content="{Binding CreateCustomerViewModel}" Grid.RowSpan="2" />
You could try the following:
Put your ItemsControl in a Grid.
Declare your ItemsControl with VerticalContentAlignment="Stretch".
It shouldn't make any difference because it's the default setting, but declare your ItemsControl with VerticalAlignment="Stretch" and try removing the Height="600".

Resources