Reputation: 4960
The behavior I'm looking for is basically that of a DockPanel, I would like the last child to fill the available space. The catch is that I would like it to be the last visible child. In my case I have two views I would like to display side by side.
So far I have tried applying two different styles to a grid, neither seems to work. I also tried using a converter which seemed to work in theory(I was able to return "Auto" using double.NaN), but I wasn't sure how to return a width of "*" from code.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*">
<ColumnDefinition.Style>
<Style TargetType="{x:Type ColumnDefinition}">
<Style.Triggers>
<DataTrigger Binding="{Binding Visibility, ElementName=ccSomeItems}" Value="Collapsed">
<Setter Property="Width" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
<ColumnDefinition Width="*">
<ColumnDefinition.Style>
<Style TargetType="{x:Type ColumnDefinition}">
<Style.Triggers>
<DataTrigger Binding="{Binding SomeOtherItems.AllOtherItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" Value="Collapsed">
<Setter Property="Width" Value="0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ColumnDefinition.Style>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<ContentControl x:Name="ccSomeItems" Content="{Binding SomeItems}" Margin="4" Visibility="{Binding SomeItems.AllItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
<ContentControl Grid.Column="1" Content="{Binding SomeOtherItems}" Margin="4" Visibility="{Binding SomeOtherItems.AllOtherItems.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
</Grid>
Upvotes: 2
Views: 1284
Reputation: 581
I know this is old, but my solution was simply to wrap the last child items in a single StackPanel like such:
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<!-- First item -->
</Grid>
<StackPanel>
<Grid Visibility="{Binding IsVisible, Converter={StaticResource BooleanVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Last child variable visibility -->
</Grid>
<Grid Visibility="{Binding IsVisble, Converter={StaticResource InverseBooleanVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Also last child variable visiblity -->
</Grid>
</StackPanel>
</DockPanel>
Upvotes: 0
Reputation: 100
I found an easier solution which is to just surround the elements you want to fill the available space with a Grid element. Thus making the grid the last element which always fills the available space. The controls within the grid can have their visibility set to whatever they want.
<DockPanel Height="31" HorizontalAlignment="Left" Margin="82,107,0,0" Name="dockPanel1" VerticalAlignment="Top" Width="286" LastChildFill="True">
<TextBlock Text="Text block" DockPanel.Dock="Left" />
<Grid>
<Button Content="Button1" Visibility="Visible" />
<Button Content="Button2" Visibility="Collapsed" />
</Grid>
</DockPanel>
Upvotes: 0
Reputation: 4960
I was able to run with Rachel's comment and find a solution using a converter.
XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Visibility, ElementName=SomeItems, Converter={StaticResource VisibilityToGridLengthConverter}}" />
<ColumnDefinition Width="{Binding Visibility, ElementName=SomeOtherItems, Converter={StaticResource VisibilityToGridLengthConverter}}" />
</Grid.ColumnDefinitions>
<ContentControl x:Name="SomeItems" Content="{Binding SomeItems}" Visibility="{Binding SubPackages.AllPackages.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
<ContentControl x:Name="SomeOtherItems" Grid.Column="1" Content="{Binding SomeOtherItems}" Visibility="{Binding Elements.AllElements.Count, Converter={StaticResource IntegerToVisibilityConverter}}" />
</Grid>
And the Converter:
[ValueConversion(typeof(Visibility), typeof(GridLength))]
public class VisibilityToGridLengthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (Visibility)value == Visibility.Collapsed ? new GridLength(0) : new GridLength(1, GridUnitType.Star);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 0