SG_90
SG_90

Reputation: 305

WPF MVVM: Dynamic drawing of a shape from a xaml file

I have a XAML file converted from an SVG file which looks like this (It represents a musical note):

    <?xml version="1.0" encoding="UTF-8"?>
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
    <Canvas Name="Layer_1" Width="50" Height="50" Canvas.Left="0" Canvas.Top="0">
        <Canvas.RenderTransform><TranslateTransform X="0" Y="0"/>
        </Canvas.RenderTransform><Canvas.Resources/>
        <!--Unknown tag: metadata--><!--Unknown tag: sodipodi:namedview-->
            <Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path2995" Fill="#FFAA0000">
                <Path.Data>
                    <PathGeometry Figures="M39.967 23.133c-0.211 0.189-0.523 0.199-0.748 0.028l-7.443-5.664l-3.526 21.095c-0.013 0.08-0.042 0.153-0.083 0.219  c-0.707 3.024-4.566 5.278-9.104 5.278c-5.087 0-9.226-2.817-9.226-6.28s4.138-6.281 9.226-6.281c2.089 0 4.075 0.466 5.689 1.324  l4.664-26.453c0.042-0.242 0.231-0.434 0.475-0.479c0.237-0.041 0.485 0.068 0.611 0.28l9.581 16.192  C40.227 22.637 40.178 22.945 39.967 23.133z" FillRule="NonZero"/>
                </Path.Data>
            </Path>
        </Canvas>
</Viewbox>

Although I'm rather new to WPF and Data Binding, I'm trying to stick to the MVVM design pattern. What I'd like to achieve here, is to dynamically draw this shape on a Canvas using a Command bound to a Button (for example). Is there a way to bind the Path.Data/PathGeometry/Figures assuming that I store the "M39.967 ..." as a string somewhere (no need to worry about file readers)?

To learn dynamic drawing I've been playing with these examples: How do you animate a line on a canvas in C#?

How to create and connect custom user buttons/controls with lines using windows forms

What I don't know is how to dynamically draw a custom shape like the one above, that could be imported by the user from a file. Please, help!

Upvotes: 2

Views: 3046

Answers (2)

Clemens
Clemens

Reputation: 128147

A valid Path Geometry string will indeed be automatically converted to a Geometry during binding.

So you may create a ViewModel like shown below (of course with also implementing INotifyPropertyChanged for all relevant properties):

public class ViewModel
{
    public string Geometry { get; set; }
}

Initialize it somehow by reading the Geometry property from file, and bind to it like this:

<Path Fill="Black" Data="{Binding Geometry}"/>

Test it with your sample geometry like this:

DataContext = new ViewModel
{
    Geometry = "M39.967 23.133c-0.211 0.189-0.523 0.199-0.748 0.028l-7.443-5.664l-3.526 21.095c-0.013 0.08-0.042 0.153-0.083 0.219  c-0.707 3.024-4.566 5.278-9.104 5.278c-5.087 0-9.226-2.817-9.226-6.28s4.138-6.281 9.226-6.281c2.089 0 4.075 0.466 5.689 1.324  l4.664-26.453c0.042-0.242 0.231-0.434 0.475-0.479c0.237-0.041 0.485 0.068 0.611 0.28l9.581 16.192  C40.227 22.637 40.178 22.945 39.967 23.133z"
};

Upvotes: 3

pushpraj
pushpraj

Reputation: 13679

you can make use of XamlReader to load an xaml from file

example

        using (FileStream fs = new FileStream(myFile, FileAccess.Read))
        {
            Viewbox viewBox = (Viewbox)XamlReader.Load(fs);
            this.Content = viewBox; //this is a window here
        }

above example loads a Viewbox from the given file and set it as a content of the window, which in turn will display the content of the file in the window

you may adjust the code as per your needs. If you need to load from a string you can use it like

        Viewbox viewBox = (Viewbox)XamlReader.Parse(xamlString);
        this.Content = viewBox;

in above examples ViewBox is used as per your xaml given in the question, it may change as per your needs as well.

Upvotes: 0

Related Questions