Binding a Canvas in Caliburn

733 views Asked by At

I am currently using Caliburn and I have the following scenario.

I have a MultiPresenterManager and the CurrentPresenter is set to a Presenter that contains a Canvas. inside the Canvas Presenter View, I have a ContentControl with the Content bound ({Binding Canvas}) and then caliburn's events hooked for the ContentControl.

I want to be able to move objects around on the canvas.

I need to 1. Bind the Canvas to some element in the view 2. Bind the events (MouseMove, MouseDown) to the Canvas

I cannot seem to get this behavior right.

Does anyone have some ideas?

1

There are 1 answers

0
Christopher Bennage On BEST ANSWER

I would recommend a very different approach, that I believe will have the same end you desire but will remove any control-specific logic from your viewmodels.

First, we'll need a logical view model that represents the objects on the canvas. Let's pretend that it's countries and the canvas is a map. Perhaps the vm would look like this:

public class Country : PropertyChangedBase {
    public string Name {get;set;}
    public double X {get;set;}
    public double Y {get;set;}
}

I omitted the INPC bits for simplicity. Next, our master viewmodel (the Presenter from your question), might look like this:

public class Map : PropertyChangedBase  {
    public ObservableCollection<Country> Countries {get;set;}    
}

We'll place a red dot on the Canvas for each country. If so, then your corresponding XAML might look like this (omitting the root element):

<ItemsControl ItemsSource="{Binding Countries}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse Fill="Red"
                     Width="16"
                     Height="16"
                     Canvas.Top="{Binding Y}"
                     Canvas.Left="{Binding X}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

If you need to handle events, just wire them up in the XAML as normal.