在画布中放置对象

时间:2014-07-12 16:15:17

标签: c# wpf xaml layout

我正在关注项目I found online for diagrams并修改其中一个形状。目标是在Path几何体周围放置一个文本框。哪个是有效的help on SO,但现在我遇到了这个问题。

路径包含在网格中,根网格中有另一个网格。第二个Grid包含一系列堆栈面板,它们位于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>

结果应该是这样的。它确实看起来像这样,直到我开始调整Path的大小。然后路径仅覆盖底部文本框的顶部。剩下的很好

预期结果

enter image description here

实际结果

enter image description here

我是否使用canvas依赖属性错误?

更新

我将所有内容都移到DockPanel中,而不是像评论中建议的那样,但结果却相同。

这是我用于包含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>

此更改的结果如下图所示。所以你有一些回溯历史,这是我试图在上面链接的SO帖子中解决的原始问题。最终的解决方案是将StackPanels放在画布上,这就解决了我的问题。除了底部画布外,它在画布上的效果很好。

更新2

我按照提供的答案,但有不良结果(实际上我昨晚在我的OP中也有同样的问题)。你可以在图像中看到,形状开始很小。在我上面提供示例项目的链接中,此模板既可以在工具箱中使用,也可以在画布上进行选择,也可以在画布上进行渲染/编辑。如果我设置最小宽度/高度,那么它会在工具箱中扭曲。此外,围绕整个模板的装饰器并不理想,因为如果装饰器仅像使用画布时那样包围形状,那将是首选。

还有其他想法吗?

使用DockPanels替换画布

enter image description here

线框现在包含整个dockpanel。

enter image description here

3 个答案:

答案 0 :(得分:2)

你去吧

这是底部面板

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

的变化:

  • VerticalAlignment="Center"到画布中的VerticalAlignment="Bottom"
  • 在画布中添加HorizontalAlignment="Center"
  • 在stackpanel中设置Canvas.Bottom="-40"

结果

result


提示

同样为ShapeInputStyle创建了一个样式。您还可以将额外的元素包装到控件模板中以使其可重用

控制模板

<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>

用法示例

    <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>

答案 1 :(得分:1)

试试这个(基本停靠模板)

<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

答案 2 :(得分:0)

<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>

除此之外,请参阅WPF Layout Tutorial