Domanda

I have the following layout:

enter image description here

The Rectangles are placed using a Grid. On top of that, I want to add more "fluid" stuff, like Paths and lines that would be located dynamically.

For instance:

  • the lines between the Rectangles, are stretched from one Rectangle's mid-point to the mid-point of the one below it
  • The left-manually-drawn-ugly-red-"path" originate from the mid-point of the left-half of the top-Rectangle, and go to the mid-point of the left Rectange below it.

So the question is: the Rectangles match Grid behavior, other stuff, like the lines, match Canvas behavior. How do I use the advantages of both these containers? can I lay one over the other?

È stato utile?

Soluzione 2

Yes you can lay the Canvas on top of a Grid, but you probably don't want to.

<Grid x:Name="container">
    <!-- We use this to put the two items in the same location -->
    <!-- i.e. Row="0" Column="0" is implicit for both the canvas and the grid below-->
  <Grid x:Name="rectangleGrid"/>
  <Canvas x:Name="shapeCanvas"/>
</Grid>

It really is that simple, but lets have a look at what we have now.

  • The shapeCanvas will be in front of the rectangleGrid (and if it isn't just tweak its ZIndex). If it has a non-transparent BackColor then you won't of course see the rectangleGrid, so you will need to sort that out.
  • If we want to line up the right hand red-line of yours we need to work out where to draw it from. Given that gridColumns don't expose sizes, then that's leftRectangle.ActualWidth + leftRectangle.Margin.Left + leftRectangle.Margin.Right + rightRectangle.Margin.Left + (rightRectangle.ActualWidth/2) and topRectangle.ActualHeight + topRectangle.Margin.Top + someConstantForHowTallThatSpacerRowIs + rightRectangle.Margin.Top + (rightRectangle.Height/2). Ouch
  • If we resize the container, then the rectangleGrid will also resize, but if you have used start-sizing for your columns then the rectangles all just resized. Now I have to go and recalculate all the sizes again.

So at this point, I'd start asking myself if I really wanted the rectangleGrid to handle the sizing or maybe I should just put everything into the Canvas.

  • You don't need to resize (although be careful because there are lots of high DPI screens out there now)
  • If you resize then the sizes are much simpler (e.g. if we assume that our margins are rectangles are 3/4 of the size and the margins 1/8 each side) so that redline top point now becomes shapeCanvas.Size *11/16 and (shapeCanvas.Height - someConstantForHowTallThatSpacerRowIs)/14

Altri suggerimenti

You don't need to mix and match your controls at all... you can chose either a Gird or a Canvas control to draw on using a Path element. Clearly, I don't want to do it all for you, so this is just a basic example of drawing in a Grid:

The end result: enter image description here

The XAML:

<Grid Width="800">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Resources>
        <Style TargetType="{x:Type Rectangle}">
            <Setter Property="Stroke" Value="Black" />
            <Setter Property="Fill" Value="White" />
            <Setter Property="StrokeThickness" Value="1" />
            <Setter Property="Width" Value="250" />
            <Setter Property="Height" Value="100" />
            <Setter Property="Rectangle.RadiusX" Value="20" />
            <Setter Property="Rectangle.RadiusY" Value="20" />
        </Style>
    </Grid.Resources>
    <Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="0" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
    <Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="1" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
    <Rectangle Grid.Row="0" Grid.ColumnSpan="2" />
    <Rectangle Grid.Row="1" Grid.Column="0" />
    <Rectangle Grid.Row="1" Grid.Column="1" />
    <Rectangle Grid.Row="2" Grid.Column="0" />
    <Rectangle Grid.Row="2" Grid.Column="1" />
    <Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 0 -100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,150,0" />
    <Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 1 100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,-250,0" />
</Grid>

You can also find the syntax that you need to use in the Path.Data property in the Path Markup Syntax page on MSDN.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top