Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placement of objects within a canvas

Tags:

c#

layout

wpf

xaml

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

like image 922
Johnathon Sullinger Avatar asked Dec 05 '25 04:12

Johnathon Sullinger


2 Answers

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>
like image 112
pushpraj Avatar answered Dec 07 '25 19:12

pushpraj


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

like image 20
Meirion Hughes Avatar answered Dec 07 '25 18:12

Meirion Hughes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!