Johnathon Sullinger
Johnathon Sullinger

Reputation: 7414

Placement of objects within a canvas

I am following along with a project I found online for diagrams and modified one of their shapes. The goal was to place a text box around the Path geometry. Which is working thanks to some help on SO but now I've got this issue.

A Path is wrapped within a Grid, with another Grid within the root Grid. The second Grid contains a series of stack panels, with the their placement around Path.

<!-- Square Shape -->
<Grid>
    <Grid Style="{StaticResource ShapeInputStyle}">
        <Canvas HorizontalAlignment="Center">
            <StackPanel Canvas.Top="-40"
                        Canvas.Left="-20">
                <TextBlock Text="Length"
                            HorizontalAlignment="Center" />
                <TextBox />
            </StackPanel>
        </Canvas>
        <Canvas VerticalAlignment="Center">
            <StackPanel Canvas.Left="-40"
                        Canvas.Top="-20">
                <TextBlock Text="Height"
                            HorizontalAlignment="Center" />
                <TextBox />
            </StackPanel>
        </Canvas>
        <Canvas VerticalAlignment="Center">
            <StackPanel Canvas.Right="-40"
                        Canvas.Top="-20">
                <TextBlock Text="Height"
                            HorizontalAlignment="Center" />
                <TextBox />
            </StackPanel>
        </Canvas>
        <Canvas VerticalAlignment="Center">
            <StackPanel Canvas.Bottom="-80"
                        Canvas.Left="-20">
                <TextBlock Text="Height"
                            HorizontalAlignment="Center" />
                <TextBox />
            </StackPanel>
        </Canvas>
    </Grid>
    <Path Style="{StaticResource Square}"
            x:Name="path"
            ToolTip="Decision">
        <controls:DesignerItem.MoveThumbTemplate>
            <ControlTemplate>
                <Path Style="{StaticResource Square_DragThumb}" />
            </ControlTemplate>
        </controls:DesignerItem.MoveThumbTemplate>
    </Path>
</Grid>

This is what the result is supposed to look like. It does actually look like this, until I start to resize the Path. Then the path overlaps ontop of the bottom textbox only. The rest are fine

Expected result

enter image description here

Actual result

enter image description here

Am I using the canvas dependenct properties wrong?

Update

I moved everything in to a DockPanel instead like suggested in the comments but end up with the same result.

This is the style that I am using for the Grid containing the StackPanels

<Style x:Key="ShapeInputStyle"
       TargetType="Grid">
    <Setter Property="Margin"
            Value="-10 -10" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=controls:DesignerItem}}"
                     Value="{x:Null}">
            <Setter Property="Visibility"
                    Value="Collapsed" />
        </DataTrigger>

        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=controls:DesignerItem}, Path=IsSelected}"
                     Value="False">
            <Setter Property="Visibility"
                    Value="Hidden" />
        </DataTrigger>
    </Style.Triggers>
</Style>

The result of this change looks like the following photo. So you have some back history, this was my original problem I was trying to solve in the SO post linked to above. The end resolution was putting the StackPanels in the canvas and it is what fixed my problem below problem. It worked fine in canvas's for everything but the bottom canvas.

Update 2

I followed the answers provided, but have undesirable results (actually I had this exact same problem in my OP last night at one point as well). You can see in the image, that the shape starts out to small. In the link I provided above where i got the sample project, this template is used both in a toolbox for the user to select and on a canvas for rendering/editing. if I set the minwidth/height then it distorts in the toolbox. Also, the adorner surrounding the entire template is not ideal, as it would be preferred if the adorner only surrounded the shape like it does when using canvases.

Any other ideas?

Replacing canvas with DockPanels

enter image description here

Wireframes now encompass the entire dockpanel.

enter image description here

Upvotes: 3

Views: 193

Answers (3)

pushpraj
pushpraj

Reputation: 13669

Here you go

this is the bottom panel

    <Canvas VerticalAlignment="Bottom" 
            HorizontalAlignment="Center">
        <StackPanel Canvas.Bottom="-40"
                    Canvas.Left="-20">
            <TextBlock Text="Height"
                        HorizontalAlignment="Center" />
            <TextBox />
        </StackPanel>
    </Canvas>

changes:

  • VerticalAlignment="Center" to VerticalAlignment="Bottom" in canvas
  • added HorizontalAlignment="Center" in canvas
  • set Canvas.Bottom="-40" in stackpanel

result

result


TIP

likewise you created a style for ShapeInputStyle. You can also wrap your extra elements into a control template to make it reusable too

control template

<ControlTemplate x:Key="EditableSides"
                 TargetType="ContentControl">
    <Grid>
        <Grid Style="{StaticResource ShapeInputStyle}">
            <Canvas HorizontalAlignment="Center">
                <StackPanel Canvas.Top="-40"
                            Canvas.Left="-20">
                    <TextBlock Text="Length"
                               HorizontalAlignment="Center" />
                    <TextBox />
                </StackPanel>
            </Canvas>
            <Canvas VerticalAlignment="Center">
                <StackPanel Canvas.Left="-40"
                            Canvas.Top="-20">
                    <TextBlock Text="Height"
                               HorizontalAlignment="Center" />
                    <TextBox />
                </StackPanel>
            </Canvas>
            <Canvas VerticalAlignment="Center">
                <StackPanel Canvas.Right="-40"
                            Canvas.Top="-20">
                    <TextBlock Text="Height"
                               HorizontalAlignment="Center" />
                    <TextBox />
                </StackPanel>
            </Canvas>
            <Canvas VerticalAlignment="Bottom"
                    HorizontalAlignment="Center">
                <StackPanel Canvas.Bottom="-40"
                            Canvas.Left="-20">
                    <TextBlock Text="Height"
                               HorizontalAlignment="Center" />
                    <TextBox />
                </StackPanel>
            </Canvas>
        </Grid>
        <ContentPresenter />
    </Grid>
</ControlTemplate>

usage example

    <ContentControl Template="{StaticResource EditableSides}">
        <Path Style="{StaticResource Decision}"
              ToolTip="Decision">
            <s:DesignerItem.MoveThumbTemplate>
                <ControlTemplate>
                    <Path Style="{StaticResource Decision_DragThumb}" />
                </ControlTemplate>
            </s:DesignerItem.MoveThumbTemplate>
        </Path>
    </ContentControl>

Upvotes: 2

Fede
Fede

Reputation: 44038

<DockPanel>
   <StackPanel DockPanel.Dock="Top" HorizontalAlignment="Center">
       <TextBlock Text="Length"
                  HorizontalAlignment="Center" />
       <TextBox />
    </StackPanel>

    <StackPanel DockPanel.Dock="Left" VerticalAlignment="Center">
        <TextBlock Text="Height"
                   HorizontalAlignment="Center" />
        <TextBox />
    </StackPanel>

    <StackPanel DockPanel.Dock="Right" VerticalAlignment="Center">
        <TextBlock Text="Height"
                   HorizontalAlignment="Center" />
        <TextBox />
    </StackPanel>

    <StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Center">
        <TextBlock Text="Height"
                   HorizontalAlignment="Center" />
        <TextBox />
    </StackPanel>

    <Path Style="{StaticResource Square}"
          x:Name="path"
          ToolTip="Decision">
        <controls:DesignerItem.MoveThumbTemplate>
            <ControlTemplate>
                <Path Style="{StaticResource Square_DragThumb}" />
            </ControlTemplate>
        </controls:DesignerItem.MoveThumbTemplate>
    </Path>
</DockPanel>

Other than that, see WPF Layout Tutorial.

Upvotes: 0

Meirion Hughes
Meirion Hughes

Reputation: 26398

Try this (basic dock template)

<DockPanel Width="200" Height="200">
    <TextBlock Text="Left" DockPanel.Dock="Left" VerticalAlignment="Center"/>
    <TextBlock Text="Right" DockPanel.Dock="Right" VerticalAlignment="Center"/>
    <TextBlock Text="Top" DockPanel.Dock="Top" HorizontalAlignment="Center" TextAlignment="Center"/>
    <TextBlock Text="bottom" DockPanel.Dock="Bottom" HorizontalAlignment="Center" TextAlignment="Center"/>

    <TextBlock Text="Center" Width="150" Height="150" Background="#FFEC7900"></TextBlock>
</DockPanel>

enter image description here

Upvotes: 1

Related Questions