How to get this window layout in WPF?
im trying to create a Window with the following layout:
Layout http://www.x-toolz.com/开发者_开发知识库downloads/layout.jpg
As you can see the window has 3 rows (15*, 70*, 15*) and 3 columns (same).
How can I redesign a rectangle to fit the geometry of the corners? If it can't be done with rectangles i would need another control that I can place content (Grid, StackPanel) in.
Any Ideas?
Thanks in advance!
MemphiZ
You could do that with a grid with 9 cells. Create 8 usercontrols to hold your outside content. If you want it size adjustable, you are going to have to work a little magic.
Each corner user control would have a 2x2 grid and for the upper left panel I will give a small example.
<UserControl
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:ec="http://schemas.microsoft.com/expression/2010/controls"
mc:Ignorable="d"
x:Class="TopLeft"
x:Name="UserControl"
d:DesignWidth="480" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Rectangle Stroke="Black" Grid.RowSpan="2" Fill="Black"/>
<Rectangle Fill="Black" Stroke="Black" Grid.ColumnSpan="2"/>
<Path Grid.Column="1" Data="M0.5,0.5 L239.5,0.5 120,120 0.5,239.5 z" Fill="Black" Grid.Row="1" Stretch="Fill" Stroke="Black" />
</Grid>
</UserControl>
In the above example a 2 x 2 grid, with a diagonal path in the bottom right. If your main window is going to resize you will have to decide whether or not your border areas will resize accordingly or be a static frame around the body of the window.
Here is the window:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MegaPanel"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="0.3*"/>
<RowDefinition Height="0.3*"/>
<RowDefinition Height="0.3*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition Width="0.3*"/>
<ColumnDefinition Width="0.3*"/>
</Grid.ColumnDefinitions>
<local:TopLeft Margin="0"/>
</Grid>
</Window>
I failed to put a Content presenter in the UserControl, but you would put that in there to add content to it.
The body area of the window would have to be handled with some care. You can set the Margin to negative values to allow the contents of the body to spill out into the frame areas.
Edit
Example:
<local:TopLeft Margin="0">
<local:TopLeft.Tag>
<ListBox/>
</local:TopLeft.Tag>
</local:TopLeft>
The above change to Top left assigns the ListBox to the Tag property of the TopLeft usercontrol. In the User control, I bound the ContentPresenter to the Tag Property of the UserControl. ListBox is assigned to the tag, ContentPresenter gets the ListBox from the Tag. Of you can regester custom properties in the UserControl codebehind if you want things in several areas.
<ContentPresenter Grid.RowSpan="2" Grid.ColumnSpan="2" Margin="0,0,125,125" Content="{Binding Tag, ElementName=UserControl}"/>
For registering custom DependencyProperties check this post out.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="15*" />
<RowDefinition Height="15*" />
<RowDefinition Height="40*" />
<RowDefinition Height="15*" />
<RowDefinition Height="15*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*" />
<ColumnDefinition Width="15*" />
<ColumnDefinition Width="40*" />
<ColumnDefinition Width="15*" />
<ColumnDefinition Width="15*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Blue">
<!-- Top Left Content Goes Here -->
</Grid>
<Grid Grid.Column="2" Grid.Row="0" Background="Aqua">
<!-- Top Middle Content Goes Here-->
</Grid>
<Grid Grid.Column="3" Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Gold">
<!-- Top Right Content Goes Here -->
</Grid>
<Grid Grid.Column="0" Grid.Row="2" Background="Magenta">
<!-- Middle LEft Content goes here -->
</Grid>
<Grid Grid.Column="4" Grid.Row="2" Background="Lime">
<!-- Middle Right Content goes here -->
</Grid>
<Grid Grid.Column="0" Grid.Row="3" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Red">
<!-- Bottom Left Content Goes Here -->
</Grid>
<Grid Grid.Column="2" Grid.Row="4" Background="DarkGoldenrod">
<!-- Bottom Middle Content Goes Here-->
</Grid>
<Grid Grid.Column="3" Grid.Row="3" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Silver">
<!-- Bottom Right Content Goes Here -->
</Grid>
<!-- This is used to shape the center" -->
<Polygon x:Name="main" Grid.Column="1" Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="3" Fill="White" Points="0,15 15,0 55,0 70,15 70,55 55,70 15,70 0,55" Stretch="Fill" StrokeThickness="0"/>
<Grid Grid.Column="1" Grid.Row="1" Grid.RowSpan="3" Grid.ColumnSpan="3" Background="Pink" >
<Grid.OpacityMask>
<VisualBrush Visual="{Binding ElementName=main}" />
</Grid.OpacityMask>
<!-- Centre Content Goes Here-->
</Grid>
</Grid>
</Grid>
</Window>
This produces this layout. The limitation is that WPF does its bounds clipping to rectangles so any content that overflows the regions will be made invisible (i.e. Clipped).
You could partially work around this by applying padding to each grid element to a create a rectangular area that fits inside each region.
精彩评论