Ask a questionAsk a question
 

Answerresizing controls on window maximize

  • Monday, November 02, 2009 8:12 AMtm200014 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    hello

    i have a window with some controls and a canvas where i can draw some lines. when i change the size of the window, i want all of the controls to maintain there size and stay in the top left corner of the window except for the canvas which should take up the rest of the space. I used the Window.SizeChanged event to do this. This works fine as long as I change the Size with the mouse dragging the bottom right corner. Although when I maximize the window, this does not work. The event gets called, but the Width and Height properties of my main window don't change. They still have the values of the small window although the window is maximized. Is there another WindowSize property which I don't know about?

    code snippet:

     

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)

    {

    Track.Width = MainWindow.Width - 310;

    Track.Height = MainWindow.Height - 150;

    }

    Track is the name of my Canvas, and it is aligned to the bottom right of my window. All of my other controls are aligned to the top left of my window (within the 150 Pixels from the top and the 310 Pixels from the left.


    Thanks!

Answers

  • Wednesday, November 04, 2009 9:23 AMDutchMarcel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    First of all, I used a ContentControl to start each section with, but you can pick any element you like. You would usually start with a new panel like a Grid or a StackPanel, to divide each section into smaller sections if that is needed. You can also start directly with the control you want to show. Your problem with the TreeView control will probably be solved if you replace the 2nd ContentControl in my example with your TreeView control (do use the same properties like DockPanel.Dock, Width and Margin). See example below.

    Your problem with asking another control for its width probably has to do with the fact that when using flow layout, the Width property is not set. But you should never use a control's Width property if you want to know its width, you should use the ActualWidth (and ActualHeight) property. One catch though, don't ask for these values to early in its life cycle, because they will only have been set when the control is fully finished rendering. But even after a resize of your window, these properties will contain the correct width and height of your control.

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="FlowLayout Window" Width="800" Height="600">
      <DockPanel LastChildFill="True">  
        
        <ContentControl DockPanel.Dock="Top" Height="150" Margin="6,6,6,3">
          <Border Background="Orange">
            <Label Content="Top Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
    
        <TreeView DockPanel.Dock="Left" Width="310" Margin="6,3,3,6">
          <!-- ... -->
        </TreeView>
        
        <Canvas Background="Khaki" Margin="3,3,6,6">
          <Label Canvas.Left="200" Canvas.Top="200" Content="Center Canvas" />
        </Canvas>
        
      </DockPanel>
    </Window>
    

    If you want your TreeView to be resizable you can try a Grid, instead of a DockPanel:

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="FlowLayout Window" Width="800" Height="600">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="150"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="310"/>
          <ColumnDefinition Width="Auto"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <ContentControl Grid.Row="0" Grid.ColumnSpan="3" Margin="6,6,6,3">
          <Border Background="Orange">
            <Label Content="Top Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
    
        <TreeView Grid.Row="1" Grid.Column="0" Margin="6,3,3,6">
          <!-- ... -->
        </TreeView>
        
        <GridSplitter Grid.Row="1" Grid.Column="1" Width="5" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
        
        <Canvas Grid.Row="1" Grid.Column="2" Background="Khaki" Margin="3,3,6,6">
          <Label Canvas.Left="200" Canvas.Top="200" Content="Center Canvas" />
        </Canvas>
        
      </Grid>
    </Window>
    

    hth,
    Marcel


    http://dutchmarcel.wordpress.com/

All Replies

  • Monday, November 02, 2009 11:45 AMDutchMarcel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    You should try to use flow layout with a requirement like this. In my example below you can still decide of you want to use a fixed or flow layout in each of the sections:

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="FlowLayout Window" Width="800" Height="600">
      <DockPanel LastChildFill="True">  
        
        <ContentControl DockPanel.Dock="Top" Height="150" Margin="6,6,6,3">
          <Border Background="Orange">
            <Label Content="Top Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
    
        <ContentControl DockPanel.Dock="Left" Width="310" Margin="6,3,3,6">
          <Border Background="Gold">
            <Label Content="Left Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
        
        <Canvas Background="Khaki" Margin="3,3,6,6">
          <Label Canvas.Left="200" Canvas.Top="200" Content="Center Canvas" />
        </Canvas>
        
      </DockPanel>
    </Window>
    

    hth,
    Marcel

    http://dutchmarcel.wordpress.com/
  • Monday, November 02, 2009 12:30 PMtm200014 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    im sorry! im new to all of this!

    Is there no property which i can read which tells me the new height and width of the maximized window? It would simplify things a lot for me!

    The code you gave me does not work. (Or I made a mistake while changing it to fit my application)
  • Monday, November 02, 2009 4:19 PMDutchMarcel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    If you want to see my code work, just paste it into Kaxaml and press F5. The canvas will resize whenever you resize the window, without any code behind.
    If you want to know more about layout than this might be a nice start: http://www.wpftutorial.net/LayoutProperties.html

    When working in WPF I would recommend using flowlayout. It's really worth looking into it.

    hth,
    Marcel

    http://dutchmarcel.wordpress.com/
  • Wednesday, November 04, 2009 8:14 AMtm200014 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    hi!

    i tried your code... it worked! im having a few troubles making it fit my needs. for example, i cannot acces the canvas.width property of the canvas in the top border control. this is very important for my program because a lot of my calculation depends on the width of the window.

    the next problem is, that i have a treeview in the left content control. i cant get it to fill up the whole content control. the only way to make it big is to set the height and width properties of the treeview and then it wont resize anymore if i resize the window.

    there is really no property from which i can read the current width and height of the main window? it would really help a lot!
  • Wednesday, November 04, 2009 9:23 AMDutchMarcel Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code
    First of all, I used a ContentControl to start each section with, but you can pick any element you like. You would usually start with a new panel like a Grid or a StackPanel, to divide each section into smaller sections if that is needed. You can also start directly with the control you want to show. Your problem with the TreeView control will probably be solved if you replace the 2nd ContentControl in my example with your TreeView control (do use the same properties like DockPanel.Dock, Width and Margin). See example below.

    Your problem with asking another control for its width probably has to do with the fact that when using flow layout, the Width property is not set. But you should never use a control's Width property if you want to know its width, you should use the ActualWidth (and ActualHeight) property. One catch though, don't ask for these values to early in its life cycle, because they will only have been set when the control is fully finished rendering. But even after a resize of your window, these properties will contain the correct width and height of your control.

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="FlowLayout Window" Width="800" Height="600">
      <DockPanel LastChildFill="True">  
        
        <ContentControl DockPanel.Dock="Top" Height="150" Margin="6,6,6,3">
          <Border Background="Orange">
            <Label Content="Top Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
    
        <TreeView DockPanel.Dock="Left" Width="310" Margin="6,3,3,6">
          <!-- ... -->
        </TreeView>
        
        <Canvas Background="Khaki" Margin="3,3,6,6">
          <Label Canvas.Left="200" Canvas.Top="200" Content="Center Canvas" />
        </Canvas>
        
      </DockPanel>
    </Window>
    

    If you want your TreeView to be resizable you can try a Grid, instead of a DockPanel:

    <Window
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="FlowLayout Window" Width="800" Height="600">
      <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="150"/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="310"/>
          <ColumnDefinition Width="Auto"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <ContentControl Grid.Row="0" Grid.ColumnSpan="3" Margin="6,6,6,3">
          <Border Background="Orange">
            <Label Content="Top Content" HorizontalAlignment="Center" VerticalAlignment="Center"/>
          </Border>
        </ContentControl>
    
        <TreeView Grid.Row="1" Grid.Column="0" Margin="6,3,3,6">
          <!-- ... -->
        </TreeView>
        
        <GridSplitter Grid.Row="1" Grid.Column="1" Width="5" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
        
        <Canvas Grid.Row="1" Grid.Column="2" Background="Khaki" Margin="3,3,6,6">
          <Label Canvas.Left="200" Canvas.Top="200" Content="Center Canvas" />
        </Canvas>
        
      </Grid>
    </Window>
    

    hth,
    Marcel


    http://dutchmarcel.wordpress.com/