c# - 在 Canvas 中放置对象

标签 c# wpf xaml layout

我正在关注一个项目 I found online for diagrams并修改了其中一个形状。目标是在路径几何图形周围放置一个文本框。这要归功于一些help on SO但现在我遇到了这个问题。

Path 包裹在 Grid 中,另一个 Grid 包裹在根 Grid 中。第二个 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>

结果应该是这样的。它实际上看起来像这样,直到我开始调整路径的大小。然后路径仅重叠在底部文本框的顶部。其他都很好

预期结果

enter image description here

实际结果

enter image description here

我是否使用了错误的 Canvas 依赖属性?

更新

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

这是我用于包含 StackPanel 的网格的样式

<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 放在 Canvas 中,这就是解决我下面问题的原因。除了底部 Canvas 之外,它在 Canvas 上的所有内容都运行良好。

更新2

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

还有其他想法吗?

用 DockPanel 替换 Canvas

enter image description here

线框现在包含整个停靠面板。

enter image description here

最佳答案

给你

这是底部面板

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

变化:

  • VerticalAlignment="Center" 到 Canvas 中的 VerticalAlignment="Bottom"
  • 在 Canvas 中添加了Horizo​​ntalAlignment="Center"
  • 在堆栈面板中设置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>

关于c# - 在 Canvas 中放置对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24714854/

相关文章:

c# - 将 Xamarin.forms 应用程序上的目标框架从 Android 8.1 更改为 Android 9(对于 Xamarin.Essentials)

c# - 在当前用户控件中单击按钮时显示不同的用户控件

c# - Nest Elasticsearch 的文档术语频率

c# - 如何以编程方式从 youtube 视频中提取音频 mp3?

WPF ListView 项目单击的名称

c# GetElementsByTagName 然后如何读取内部标签值

c# - 从文件夹中的图像列表显示图像 C# UWP

silverlight - 自定义 UserControl 属性未通过 Silverlight 4 中的 XAML DataBinding 设置

c# - 如何在 asp.net core rc2 中获取 Controller 的自定义属性

c# - WPF 中 ReactiveUI 的 IViewFor<T> (及其实现类型)的目的是什么?