仅从“画布”中删除CoordinateSystem

时间:2014-09-03 07:57:50

标签: c# wpf canvas resize coordinate-systems

我尝试使用坐标系在Canvas上绘制树。我还没有那么远,我可以画树本身,此刻我试图让坐标系更灵活,所以当我调整窗口和画布时,它会被重绘它。(这意味着扩大/缩小它的轴,而不是规模。)

我已经阅读了一些关于画布和删除其子元素的主题,我找到了一个解决方案。问题是这个解决方案对我来说没有问题,因为它在每次调整大小事件时都只会删除一行坐标系。

用于绘制坐标系的所有线都以CoordinateSystemIn开头的UID。

目前我的代码是:

Canvas = Anzeige;
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
    if (MainWindowLoaded)
    {
        foreach (UIElement Element in Anzeige.Children)
        {
            if (Element.Uid.StartsWith("CoordinateSystemIn"))
            {
                Anzeige.Children.Remove(Element);   
            }
        }
        Stift.DrawCoordinateSystem(Anzeige.ActualWidth, Anzeige.ActualHeight, 25);
    }
}

是否有其他解决方案一次重绘整个坐标系,而不仅仅是每次调整大小事件的行?

2 个答案:

答案 0 :(得分:1)

Canvas放入ViewBox - 后者会自动将画布调整为适当的大小。您的代码可能如下所示:

<Window x:Class="WpfAccessControlFromResources.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Viewbox>
        <Canvas Width="80"
                Height="80">
            <Path Stroke="DarkGray">
                <Path.Data>
                    <GeometryGroup>
                        <EllipseGeometry RadiusX="40" RadiusY="40" Center="40, 40" />
                        <LineGeometry StartPoint="15, 40" EndPoint="65, 40" />
                        <LineGeometry StartPoint="40, 15" EndPoint="40, 65" />
                    </GeometryGroup>
                </Path.Data>
            </Path>
        </Canvas>
    </Viewbox>
</Window>

这样你就不必自己弄乱坐标了。

Marv评论后更新

实际上,我认为你应该将坐标系封装在一个单独的类中。此类将派生自System.Windows.Controls.Panel,并将覆盖ArrangeOverrideMeasureOverride方法以定位子元素。在这些前一种方法中,您还可以添加/删除显示坐标系的不必要的PathGeometries。代码可能有点像这样:

public class CoordinateSystem : Panel
{
    // This element will display the actual coordinate system
    // It must be added to the collection of InternalChildren
    private Path _coordinateSystemPath;


    // This method is used to determine how much space the children want to have
    protected override Size MeasureOverride(Size availableSize)
    {
        Size infiniteSize = new Size(double.PositiveInfinity, double.PositiveInfinity);
        Size desiredSize = new Size();

        // Measure how many space the items you want to display need
        foreach (var child in InternalChildren)
        {
            child.Measure(infiniteSize);
            // Check at which position this child wants to be and
            // calculate the desired size of the coordinate system
        }
        return desiredSize;
    }

    // this method will arrange the path for the coordinate system as well as
    // all the children that will be displayed
    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (var child in InternalChildren)
        {
            if (child == _coordinateSystemPath)
            {
                // Update the PathGeometry of this path according to provided finalSize here
                continue;
            }

            child.Arrange(child.DesiredSize);
        }
    }
}

请注意,这只是草图而不是全班。在这种情况下,如果您愿意,还可以集成缩放系数和坐标系原点的平移。

无论如何,虽然这个解决方案可能是最关注的分离问题,但它还需要对WPF布局系统以及相当多的工作和测试有一个很好的理解。您可以在此处详细了解此主题:http://msdn.microsoft.com/en-us/library/ms754152(v=vs.110).aspx

答案 1 :(得分:0)

您可能想要使用的是Viewbox class。这将自动为您完成所有调整大小(没有一行程序代码)。举个例子:

<Viewbox>
    <Path StrokeThickness="1" Stroke="Black" Data="M0,0 L25,25 M0,25 L25,0"/>
</Viewbox>

我们在这里有一个简单的Path&#39; X&#39;代表您的Canvas内容。它最初非常小,或没有Viewbox,只有25 X 25像素。但是,一旦进入Viewbox,它就会自动填充其提供的空间。您可能还会发现StretchStretchDirection属性对您有用。

只需将Canvas添加到ViewBox并进行试验即可确定它是否符合您的需求。