In WPF/XAML, you will very often create your custom templates for containers, and one of the issues is to properly adjust the template contents with its container.
The most common problem is making the template fill the container completely. This is done with the properties HorizontalContentAlignment
and VerticalContentAlignment
of the container, setting them to Stretch
. You can then use the Margin
of your top level template element for positioning.
1 2 |
<ListBox ItemsSource="{Binding Series}" HorizontalContentAlignment="Stretch"> |
When we need more precise control, we can do calculations with a converter based on the actual layout parameters of the container. You get that info with a RelativeSource
binding in FindAncestor
mode.
1 2 3 4 5 6 |
<ListBox ItemsSource="{Binding Series}"> <ListBox.ItemTemplate> <DataTemplate> <Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}, Converter={StaticResource AddConv}, ConverterParameter=-42}"> |
This requires you to add a simple converter to your project to do the calculation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[ValueConversion(typeof(double), typeof(double))] public class DoubleAddConverter : IValueConverter { private CultureInfo usCulture = CultureInfo.CreateSpecificCulture("en-US"); object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) { try { var param = double.Parse( parameter as string, usCulture); return Math.Max(0.0d, (double) value + param); } catch { return value; } } object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return DependencyProperty.UnsetValue; } } |
and include it in your application resources
1 2 |
<Application.Resources> <local:DoubleAddConverter x:Key="AddConv"/> |