databinding to a custom control

Topics: Conventions
Aug 21, 2011 at 8:12 PM
Edited Aug 22, 2011 at 8:21 PM

I have been working on a databinding issue for several hours now. This is a wpf project. I have a custom control with a property like "public object selectedObject{get;set;} .... When I drop that control onto a page I want to bind to a property in the pages view model named SelectedObject. ... 

I have named them the same. I have added a ElementConvention. I have added dependency properties. I have tried native binding. However, I can't get that control to pick up the property. If you could give me a couple of sentences about what to try it would greatly be appreciated.

Example code:

<UserControl x:Class="WpfApplication1.QuickControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="91,132,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Text="" />
    </Grid>
</UserControl>


<Window xmlns:my="clr-namespace:WpfApplication1"  x:Class="WpfApplication1.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" mc:Ignorable="d"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="375" d:DesignWidth="393" SizeToContent="WidthAndHeight">

 <Grid Background="White">
        <my:QuickControl x:Name="MyValue" />
 </Grid>

</Window>

namespace WpfApplication1 {
    using System.ComponentModel.Composition;
    using Caliburn.Micro;

    [Export(typeof(IShell))]
    public class ShellViewModel :
        Conductor<object>, IShell
    {

        private string _myValue;
        public string MyValue { get { return this._myValue; } set { this._myValue = value; this.NotifyOfPropertyChange(() => MyValue); } }
   
    }
}
 


Aug 22, 2011 at 9:30 PM
Edited Aug 22, 2011 at 9:30 PM

I added this element convention

ConventionManager.AddElementConvention<WpfApplication1.QuickControl>(WpfPropertyGrid.HotObject, "SelectedObject", "SelectedObjectChanged" );

along with this property

public static readonly DependencyProperty HotObject = DependencyProperty.Register("SelectedObject", typeof(object), typeof(WpfApplication1.QuickControl), new UIPropertyMetadata(null));

 

but it didn't help. :( 

Aug 23, 2011 at 8:09 AM
Edited Aug 23, 2011 at 8:10 AM

Why convention?

First your MyValue (renamed to MyQuickControl below ) property should be of type QuickControl (or at least object) like this:

 

[Import]
public QuickControl MyQuickControl { get; set; }

 

Now you are able to access every public property and method of your QuickControl from within your ShellViewModel, e.g.:

 

public object SelectedObject
{
   get {return _selectedObject;}
   set
   {
      _selectedObject = value;
      NotifyOfPropertyChang(() => SelectedObject);
      //and here you could access your QucikControl properties or methods:
      MyQuickControl.SelectedObject = value;
   }
}

 
Aug 23, 2011 at 3:27 PM

doing that gives me a control on my view model but it is not the same instance of control that is showing on the view...

Aug 23, 2011 at 6:59 PM
Edited Aug 23, 2011 at 7:00 PM

Oh sorry, I was one step further...

just put your UserControl QuickControl into a file named QuickControlView.xaml. Then add a ViewModel for this view named QuickControlViewModel.cs.

In your ShellView, add a ContentControl and bind it to a property which represents your view model:

 

<ContentControl x:Name="QuickControlVM" />

 

In ShellViewModel, import (MEF, shared instance) your QuickControlViewModel:

 

[Import]
public QuickControlViewModel QuickControlVM {get;set;}

 

Now you have access to your view model and every public property or method in it:

public object SelectedObject
{
   get {return _selectedObject;}
   set
   {
      _selectedObject = value;
      NotifyOfPropertyChang(() => SelectedObject);
      //and here you could access your QuickControlVM's properties or methods    
    QuickControlVM.SelectedObject = value;
   }
}
That's it.