Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am creating an application in WPF using the MVVM approach. I am fairly new to the topic and I'm looking on pointers how to achieve the following: I have created a canvas in XAML, as follows:

<canvas name = "myCanvas">
...
</canvas>

I added a button, also in XAML, which I want to use to draw (programmatically) some basic shapes (line, rectangle, etc.) onto the existing canvas on mouse click. Since I'm using the MVVM approach, the button's command has to be bound to a method, as follows:

<Button name="myButton" Command="{Binding myMethod, Mode=OneWay}">
...
</Button>

I got the binding itself to work fine and I created the drawings and shapes in C#, but I don't understand how can I put the shapes onto the canvas that was created in XAML. How can I address the canvas pre-made in XAML from my method? How do I go about this?

Edit:

The point of this is that I want to generate shapes based on data to visualise it. So, if my input has, say, 3 elements of type A, I want to create 3 rectangles and display them on the canvas. Later I want to make them clickable and display some information about them on click. MVVM is a set requirement for me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
240 views
Welcome To Ask or Share your Answers For Others

1 Answer

In your view model you should have a representation of the shapes that does not use any UI elements:

public class ShapeItem
{
    public Geometry Geometry { get; set; }
    public Brush Fill { get; set; }
    public Brush Stroke { get; set; }
}

public class ViewModel
{
    public ObservableCollection<ShapeItem> ShapeItems { get; set; }
}

You would then use an ItemsControl with an appropriate ItemsPanel and ItemTemplate to visualize the shape items:

<ItemsControl ItemsSource="{Binding ShapeItems}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Path Data="{Binding Geometry}"
                  Fill="{Binding Fill}"
                  Stroke="{Binding Stroke}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The view model might be initialized like shown below, and items may be added similarly when an appropriate command method is executed:

var vm = new ViewModel();
vm.ShapeItems = new ObservableCollection<ShapeItem>();
vm.ShapeItems.Add(
    new ShapeItem
    {
        Geometry = new EllipseGeometry(new Point(100, 100), 100, 50),
        Fill = Brushes.LightBlue
    });
vm.ShapeItems.Add(
    new ShapeItem
    {
        Geometry = new RectangleGeometry(new Rect(150, 100, 200, 100)),
        Fill = Brushes.Azure,
        Stroke = Brushes.Black
    });

DataContext = vm;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...