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コントロールを使用する場合、このコードは正常に機能します。

クローンされたユーザーコントロールがまだ視覚的な階層の一部ではないという問題があると思います。ただし、上記のコードを機能させるために、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 に答える