WinRT XAML trying to use a Path defined in Resourc

2019-08-06 12:02发布

I'm using Visual Studio 2013 to create a Windows App Store app. I created a ResourceDictionary in a file called AllButtonShapes.xaml to store the Paths for all of the shapes I use on my buttons. I added AllButtonShapes.xaml to my app resources:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="AllButtonShapes.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Three of the paths defined are x:Key'd as ShapeView_N, ShapeView_AccInt, and ShapeView_XPYR.

I have a custom UserControl called DynamicButton which users 3 of the paths.

<local:DynamicButton x:Name="Button_N_AccInt_XPYR" Grid.Row="1" Grid.Column="1" 
    Margin="126,82,158,56" 
    ShapeWhite="{StaticResource ShapeView_N}" 
    ShapeBlue="{StaticResource ShapeView_AccInt}" 
    ShapeOrange="{StaticResource ShapeView_XPYR}"/>

In the XAML designer, I see the button render correctly with those 3 paths. The DynamicButton xaml uses a Grid (x:Name="ShapeGrid"). When one of the three Shapes is set on the DynamicButton (via the attribute shown above), the code adds that Shape as a child of the grid.

this.ShapeGrid.Children.Add(this.shapeBlue);

However, when I run the app, it crashes with the following error:

"Element is already the child of another element."

I'm not using any of the shapes anywhere else (still in initial testing, so I've only got one button on the screen). I have no idea what it could already be a child of. I debugged it and looked this.shapeBlue.Parent, but it was null.

a) Assuming the Path is already a child of another element, how do I remove it from that element so I can use it?

b) Is there another, more proper, way to define reusable paths so that I can use them on my buttons?

I can't just define the paths inline in a UserControl, because I need to use the same Shape in different places.

1条回答
仙女界的扛把子
2楼-- · 2019-08-06 12:44

I'm not perfectly happy with the solution, but this is what I ended up doing:

I generated all of my Paths using the compact markup syntax:

<x:String x:Key="ShapeView_N_String">M 131.12,10.6 L 141.17,10.6 L 141.17,85.34 L 132.07,85.34 L 82.68,27.78 L 82.68,85.34 L 72.74,85.34 L 72.74,10.6 L 81.31,10.6 L 131.12,68.65 L 131.12,10.6 L 131.12,10.6</x:String>

Then in my DynamicButton UserControl, instead of passing the Shape/Path itself, I just pass the String resource:

<local:DynamicButton
    Grid.Row="0" Grid.Column="0"
    Height="Auto" Width="Auto" 
    ShapeStringWhite="{StaticResource ShapeView_N_String}"
/>

In my DynamicButton class, I've got a getter/setter for ShapeStringWhite:

private string _shapeStringWhite;
public string ShapeStringWhite
{
    get { return this._shapeStringWhite; }

    set
    {
        this._shapeStringWhite = value;
        this.ShapeWhite = this.createPathFromString(this._shapeStringWhite);

    }
}

private Path createPathFromString(string pathMarkup)
{
    Path path = (Path)XamlReader.Load(String.Format(@"<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Data=""{0}"" />", pathMarkup));
    return path;
}
查看更多
登录 后发表回答