MikeR
MikeR

Reputation: 3075

Automatic resize of nested UserControl does not work

In my application I use a ContentControl and dynamically fill it with a custom UserControl, using binding on Content to bind to a FrameworkElement. [EDITED: added example code to show the problem]

After some input of Steven and Charleh I created a small MVVM project to reproduce the problem. My MainWindow now looks like that:

    <Window x:Class="ResizeExample.MainWindow"
    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"
    xmlns:localVM="clr-namespace:ResizeExample.ViewModels"
    xmlns:local="clr-namespace:ResizeExample"
    Title="ResizeExample"
    WindowStartupLocation="CenterScreen"
    Height="459"
    Width="795">
<Window.Resources>
    <localVM:MainWindowViewModel x:Key="Windows1ViewModel" />
</Window.Resources>

<Grid DataContext="{StaticResource Windows1ViewModel}">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Canvas Grid.Row="0">
        <Menu DockPanel.Dock="Top"/>
        <Label Content="Any Label on the right side" Canvas.Right="0" Canvas.Bottom="0"/>
    </Canvas>
    <Grid Grid.Row="1" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch">
        <ContentControl Name="ControlCanvas" Content="{Binding Path=externalView}" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"  VerticalContentAlignment="Stretch"/>
    </Grid>
</Grid>

Setting externalView works fine, but it does not resize when the window is resized. Here how I implemented it in the ViewModel:

    private FrameworkElement _externalView;
    public FrameworkElement externalView
    {
        get { return this._externalView; }
        set
        {
            if (this._externalView != value)
            {
                this._externalView = value;
                RaisePropertyChanged(() => externalView);
            }
        }
    }

    public MainWindowViewModel()
    {
        externalView = new UserControl1();
    }

The UserControl contains a TabControl (which should resize) and everything else is in the TabControl. The TabControl contains some labels, text boxes and buttons (which should not resize) and a DataGrid (which should resize). At the moment the complete TabControl is minimized, because no size is set and it will not resize.

<UserControl x:Class="ResizeExample.Views.UserControl1"
        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" 
         mc:Ignorable="d" 
         d:DesignHeight="411" d:DesignWidth="805" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" >
<Grid HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"   >
    <TabControl HorizontalAlignment="Left" Name="tabControl1" VerticalAlignment="Top">
        <TabItem Header="Tab1" Name="Tab1">
            <Grid />
        </TabItem>
        <TabItem Header="Tab2" Name="Tab2">
            <Grid>
                <TextBox Height="23" HorizontalAlignment="Left" Margin="6,6,0,0" Name="textBox1" VerticalAlignment="Top" Width="357" />
                <Label Content="Input some data 1:" Height="28" HorizontalAlignment="Left" Margin="6,29,0,0" Name="label1" VerticalAlignment="Top" />
                <Label Content="Input some data 2:" Height="28" HorizontalAlignment="Left" Margin="6,57,0,0" Name="label2" VerticalAlignment="Top" />
                <Label Content="Input some data 3:" Height="28" HorizontalAlignment="Left" Margin="6,85,0,0" Name="label3" VerticalAlignment="Top" />
                <DataGrid AutoGenerateColumns="False" MinHeight="200" HorizontalAlignment="Left" Margin="6,113,0,0" Name="releaseNotesGrid" VerticalAlignment="Top" MinWidth="780" />
            </Grid>
        </TabItem>
    </TabControl>
</Grid>
</UserControl>

I thought the controls would resize automatically, but this is not working. While I'm new to WPF and MVVM, it could be that I missed something basic.

I found the following thread after which I removed the sizes and added the alignments, but this didn't solve my problem.

Upvotes: 1

Views: 6003

Answers (3)

MikeR
MikeR

Reputation: 3075

I solved it now by testing a bit. The problem was the TabControl and DataGrid in the UserControl, which had Alignments that did not work with the stretch. This is now my UserControl1 and it works fine for me:

<UserControl x:Class="ResizeExample.Views.UserControl1"
        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" 
         mc:Ignorable="d" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch"  VerticalContentAlignment="Stretch">
<Grid HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" >
    <TabControl HorizontalAlignment="Stretch" Name="tabControl1" VerticalAlignment="Stretch">
        <TabItem Header="Tab1" Name="Tab1">
            <Grid />
        </TabItem>
        <TabItem Header="Tab2" Name="Tab2" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch">
            <Grid>
                <TextBox Height="23" HorizontalAlignment="Left" Margin="6,6,0,0" Name="textBox1" VerticalAlignment="Top" Width="357" />
                <Label Content="Input some data 1:" Height="28" HorizontalAlignment="Left" Margin="6,29,0,0" Name="label1" VerticalAlignment="Top" />
                <Label Content="Input some data 2:" Height="28" HorizontalAlignment="Left" Margin="6,57,0,0" Name="label2" VerticalAlignment="Top" />
                <Label Content="Input some data 3:" Height="28" HorizontalAlignment="Left" Margin="6,85,0,0" Name="label3" VerticalAlignment="Top" />
                <DataGrid AutoGenerateColumns="False" MinHeight="200" Margin="6,113,0,0" Name="releaseNotesGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="780" />
            </Grid>
        </TabItem>
    </TabControl>
</Grid>
</UserControl>

Thanks to Steven and Charleh to point me to the right direction.

Upvotes: 4

Charleh
Charleh

Reputation: 14002

In addition to Stevens answer, you may also need to set ContentControl.HorizontalContentAlignment and ContentControl.VerticalContentAlignment to Stretch as ContentControl defaults are Left and Top respectively (as far as I recall)

Otherwise even though the ContentControl will fill the parent container, the content won't

Edit: Here's the default template for the ContentControl showing the default values...

<Style TargetType="ContentControl">
  <Setter Property="Foreground" Value="#FF000000"/>
  <Setter Property="HorizontalContentAlignment" Value="Left"/>
  <Setter Property="VerticalContentAlignment" Value="Top"/>
  <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="ContentControl">
              <ContentPresenter
                  Content="{TemplateBinding Content}"
                  ContentTemplate="{TemplateBinding ContentTemplate}"
                  Cursor="{TemplateBinding Cursor}"
                  Margin="{TemplateBinding Padding}"
                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
          </ControlTemplate>
      </Setter.Value>
  </Setter>

Upvotes: 2

Steven Jeuris
Steven Jeuris

Reputation: 19130

Canvas does not automatically resize it's child contents to the container size.

Try using e.g. Grid instead.

Upvotes: 1

Related Questions