0

我玩过一点WPF。我想要做的是将自定义控件从模板调色板窗口拖到另一个窗口的画布上,并在那里创建该自定义控件的克隆。这与您在 Visio 中看到的非常相似。

为了从调色板中克隆模板控件,我滥用了 XamlWriter 和 XamlReader 的序列化和反序列化功能。

在我的下拉回调中,我有以下代码:

private void drawingCanvas_Drop(object sender, DragEventArgs e)
{
    DrawingShape shape = (DrawingShape)e.Data.GetData(typeof(DrawingShape));
    if (shape != null)
    {
        Canvas target = this.drawingCanvas;
        Point p = e.GetPosition(target);

        string xamlString = System.Windows.Markup.XamlWriter.Save(shape);
        DrawingShape c = (DrawingShape)System.Windows.Markup.XamlReader.Parse(xamlString);

        Canvas.SetLeft(c, p.X - c.Width / 2);
        Canvas.SetTop(c, p.Y - c.Height / 2);
        target.Children.Add(c);

        this.shapesPalette.shapesGallery.ClearValue(ListView.SelectedIndexProperty);
    }
}

我的用户控件如下所示:

<UserControl x:Class="MyNamespace.Graphics.DrawingShape"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="60" d:DesignWidth="60">
    <Grid Width="Auto" Height="Auto" >
        <Grid.RowDefinitions>
            <RowDefinition Height="38"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Canvas HorizontalAlignment="Center" Grid.Row="0" Width="38" Height="38" Canvas.Left="0" Canvas.Top="0">
            <Path x:Name="Path" Width="35.8774" Height="31.2047" Canvas.Left="1.0613" Canvas.Top="3.29528" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF230FD2" Fill="#FF0096FF" Data="F1 M 19,3.79528L 1.5613,34L 36.4387,34L 19,3.79528 Z "/>
        </Canvas>
        <Label x:Name="Label" HorizontalAlignment="Center" Grid.Row="1">MyLabel</Label>
    </Grid>
</UserControl>

但是,Canvas.SetLeft()不要Canvas.SetTop()做任何事情。克隆始终添加到目标画布的左上角。如果我使用任何其他 WPF-Control 而不是我的用户控件,则此代码可以正常工作。

我想,克隆的用户控件还不是任何视觉层次结构的一部分,存在问题。但是,我想知道 MS 控件在哪些方面做得更好才能使上述代码正常工作。由于我对 WPF 很陌生,所以我不确定我应该寻找什么来修复我的用户控件。非常感谢任何指针。

4

1 回答 1

0

我已经不再通过XamlWriter/进行克隆XamlReader(无论如何它仅用于原型设计),现在在强制布局更新后使用ActualWidth/ :ActualHeight

private void drawingCanvas_Drop(object sender, DragEventArgs e)
{
    DrawingShape templateShape = (DrawingShape)e.Data.GetData(typeof(DrawingShape));
    if (templateShape != null)
    {
        Canvas target = this.drawingCanvas;
        Point p = e.GetPosition(target);

        DrawingShape addedShape = new DrawingShape();
        addedShape.IsDraggingEnabled = true;

        target.Children.Add(addedShape);
        addedShape.UpdateLayout();
        addedShape.RenderTransform = new TranslateTransform(p.X - addedShape.ActualWidth / 2, p.Y - addedShape.ActualHeight / 2);
        this.shapesPalette.shapesGallery.ClearValue(ListView.SelectedIndexProperty);
    }
}

但是,我希望此解决方案可以与 XamlWriter/XamlReader-cloning 一起使用。

于 2012-09-22T13:03:43.887 回答