开发者

Looking for some WPF layout advice

I am trying to model the layout that is displayed in this image.

If you take a look, it has a number of textBoxes/checkboxes/buttons, a couple of diagonal controls, and another separate control (in a red outline).

The bottom screenshot shows what I would like to happen when a checkbox is checked in that separate control.

Any tips on how to lay this out and handle those diagonal portions? I tried just rotating textBlocks with borders but then the borders remain as rectangular, not cut off as in the image. I also had some trouble with getting them to position properly. I would also need the width of those dia开发者_StackOverflowgonal sections to be bound somehow to the checkbox/textBox portion of that separate control in the red border.

Is my only choice to rotate borderless textBlocks and draw the lines myself using Paths and for the width expanding, bind it to some property of my separate control?

Thanks for any advice.


This looked like a fun challenge. Give the following XAML a try. It will automatically adjust the size of the columns as the content expands. The key is placing some canvas elements in a grid to allow the lines of the borders to flow into the adjacent cells. This could certainly be cleaned up with some styles and will be a little fragile if you need to tweak the sizes, but I think it demonstrates the approach:

Looking for some WPF layout advice

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ButtonStyleTestApp.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">   

<Grid x:Name="LayoutRoot" Background="#FF44494D" SnapsToDevicePixels="True">
    <Grid.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    </Grid.Resources>

    <Grid Background="#DDD">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition MinWidth="30" Width="Auto"/>
            <ColumnDefinition MinWidth="30" Width="Auto"/>
            <ColumnDefinition MinWidth="30" Width="Auto"/>
            <ColumnDefinition MinWidth="30" Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="60"/>
            <RowDefinition Height="30"/> 
        </Grid.RowDefinitions>

        <Border BorderThickness="1 1 0 1" BorderBrush="#888" Grid.Column="0" Grid.Row="1">
            <TextBox Margin="10 5" VerticalAlignment="Center"/>         
        </Border>

        <Border BorderThickness="1 1 0 1" BorderBrush="#888" Grid.Column="1" Grid.Row="1">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                <CheckBox x:Name="CheckBox1" Margin="5" VerticalAlignment="Center"></CheckBox>
                <TextBox Visibility="{Binding IsChecked, ElementName=CheckBox1, Converter={StaticResource BooleanToVisibilityConverter}}" Width="100" Margin="5" VerticalAlignment="Center"/>
            </StackPanel>               
        </Border>

        <Border BorderThickness="1 1 0 1" BorderBrush="#888" Grid.Column="2" Grid.Row="1">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                <CheckBox x:Name="CheckBox2" Margin="5" VerticalAlignment="Center"></CheckBox>
                <TextBox Visibility="{Binding IsChecked, ElementName=CheckBox2, Converter={StaticResource BooleanToVisibilityConverter}}" Width="100" Margin="5" VerticalAlignment="Center"/>
            </StackPanel>               
        </Border>

        <Border BorderThickness="1 1 0 1" BorderBrush="#888" Grid.Column="3" Grid.Row="1">
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                <CheckBox x:Name="CheckBox3" Margin="5" VerticalAlignment="Center"></CheckBox>
                <TextBox Visibility="{Binding IsChecked, ElementName=CheckBox3, Converter={StaticResource BooleanToVisibilityConverter}}" Width="100" Margin="5" VerticalAlignment="Center"/>
            </StackPanel>               
        </Border>

        <Border BorderThickness="1" BorderBrush="#888" Grid.Column="4" Grid.Row="1">
            <Button Margin="3" FontSize="10" VerticalAlignment="Center" Width="40">Click</Button>           
        </Border>           

        <Canvas Grid.Column="1">
            <Grid ClipToBounds="False" Canvas.Top="30">
                <Border 
                BorderBrush="#888" 
                BorderThickness="0 1 0 0" 
                RenderTransformOrigin="0 0" 
                Height="20"
                Width="100" 
                Margin="0 0 0 -80">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="-45"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            <TextBlock VerticalAlignment="Center" TextAlignment="Left" Margin="21 1 1 1" FontSize="11">
                Testing 1
            </TextBlock>
        </Border>
        </Grid>
        </Canvas>

        <Canvas Grid.Column="2">
            <Grid ClipToBounds="False" Canvas.Top="30">
                <Border 
                BorderBrush="#666" 
                BorderThickness="0 1 0 0" 
                RenderTransformOrigin="0 0" 
                Height="20"
                Width="100" 
                Margin="0 0 0 -80">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="-45"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            <TextBlock VerticalAlignment="Center" TextAlignment="Left" Margin="21 1 1 1" FontSize="11">
                Testing 2
            </TextBlock>
        </Border>
        </Grid>
        </Canvas>

        <Canvas Grid.Column="3">
            <Grid ClipToBounds="False" Canvas.Top="30">
                <Border 
                BorderBrush="#666" 
                BorderThickness="0 1 0 0" 
                RenderTransformOrigin="0 0" 
                Height="20"
                Width="100" 
                Margin="0 0 0 -80">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="-45"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
            <TextBlock VerticalAlignment="Center" TextAlignment="Left" Margin="21 1 1 1" FontSize="11">
                Testing 3
            </TextBlock>
        </Border>
        </Grid>
        </Canvas>

        <Canvas Grid.Column="4">
            <Grid ClipToBounds="False" Canvas.Top="30">
                <Border 
                BorderBrush="#666" 
                BorderThickness="0 1 0 0" 
                RenderTransformOrigin="0 0" 
                Height="20"
                Width="100" 
                Margin="0 0 0 -80">
                <Border.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="-45"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </Border.RenderTransform>
        </Border>
        </Grid>
        </Canvas>           
    </Grid>     
</Grid>
</Window>

I hope it helps.


It's definitely doable with borders and textblocks but it's tedious.

you'd have to play with negative margins a lot.

You could work it out with images instead of borders but you still need the textblocks on an angle using rendertransform

I'd definitely approach it using a Grid with a lot of columns of width Auto, place the easy components first then the tricky ones and do the rotations + neg margins last.

HTH.


As far as handling the diagonal elements goes, try putting the TextBlock within a Border, and transforming the border with a RotateTransform and SkewTransform. This should get you started:

<Grid HorizontalAlignment="Left" Height="100" Margin="64,60.5,0,0" VerticalAlignment="Top" Width="100" Background="Blue">
        <Border BorderBrush="Black" BorderThickness="1" Margin="20,25.5,20.5,41.5" RenderTransformOrigin="0.5,0.5">
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform AngleY="20"/>
                    <RotateTransform Angle="90"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Border.RenderTransform>
            <TextBlock TextWrapping="Wrap" Text="TextBlock" RenderTransformOrigin="0.5,0.5">
                <TextBlock.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform/>
                        <SkewTransform/>
                        <RotateTransform Angle="180"/>
                        <TranslateTransform/>
                    </TransformGroup>
                </TextBlock.RenderTransform>
            </TextBlock>
        </Border>
    </Grid>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜