Search code examples
c#wpfcaliburn.microcaliburn

Binding an UserControl with a constructor to ViewModel


Just started using Caliburn and WPF and got stuck on including an UserControl with a parameter to my Window.

Got one class named Item with a property named SellPrice which returns a Money object. I want to transfer this Money object to a UserControl to format the data in this object. How do I transfer the object? Do I need the use the constructor?

MainView.xaml

<DataGridTemplateColumn Header="Sell Price">
     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
            <local:MoneyControlView/>
         </DataTemplate>
     </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn>

Above code works fine if there wouldn't be any parameter but how do I pass the Money object?

I did try to do it via DependencyProperty as follows:

public partial class MoneyControlView : UserControl
{
    public static readonly DependencyProperty MoneyProperty = DependencyProperty.Register
    (
            "Money",
            typeof(Money),
            typeof(MoneyControlView),
            new PropertyMetadata(new Money())
    );

    public Money Money
    {
        get { return (Money)GetValue(MoneyProperty); }
        set { SetValue(MoneyProperty, value); }
    }

    public MoneyControlView()
    {
        InitializeComponent();
        DataContext = new MoneyControlViewModel(Money);
    }
}

However, when using it:

<local:MoneyControlView Money="{Binding BuyPrice}"/>

it doesn't work. the Property remains empty.


Solution

  • It isn't clear from your question how an Item relates to a MoneyControlViewModel. There are several potential changes to the listed code, though:

    1) Change Collection<Item> to ObservableCollection<Item>

    2) Assuming the Item class has a Money property that returns a MoneyControlViewModel... In the XAML, change the DataGridTemplateColumn:

    <DataGridTemplateColumn Header="Sell Price">
         <DataGridTemplateColumn.CellTemplate>
             <DataTemplate>
                <ContentControl x:Name="SellPrice" cal:View.Model="{Binding Money}"/>
             </DataTemplate>
         </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn>
    

    This part of your question is not clear:

    How do I implement the Money UserControl for each Item in my list? Wouldn't be a problem if I got the current index of the DataGrid in order to retrieve the Money object from the Item...

    It looks like you might want an ItemsControl and use a DataTemplate with a MoneyControl. This question might help: ItemsControl ItemTemplate Binding