Binding dependency properties outside of the visual tree

Topics: Conventions, Getting Started
Aug 21, 2013 at 12:19 AM

I am fairly new to Caliburn.micro, so I'd first like to apologize if what I ask ends up being too simple... but I have done my fair bit of research and can't seem to find an answer.

I have a view where I have created a dependency property in my code-behind. This property is a non-visual property, I use it to initialize the view in certain ways depending on the value of such property (details of these being not relevant). Here is the definition of the property in my code-behind class:
public partial class SelectionListView : UserControl
    public string ListType
        get { return (string)GetValue(ListTypeProperty); }
        set { SetValue(ListTypeProperty, value); }
    public static readonly DependencyProperty ListTypeProperty =
        DependencyProperty.Register("ListType", typeof(string), typeof(SelectionListView), null);
In my viewModel (called SelectionListViewModel), I have a corresponding property ListType and I'd like to bind both properties (the view's and the viewModel's). And this is where I have run into a dead-end. Although I have followed the naming conventions correctly, or at least I believe so, the automatic binding performed by the Caliburn.micro framework does not seem to bind both properties... however, on reading the documentation I have found that this is to be expected since the ViewModelBinder only searches the visual tree... and since this property is a non-visual element I imagine it cannot be a candidate for automatic binding through the framework. I believe I have "confirmed" this is actually what is going on because, if I happen to create a visual element in the view (for instance, a TextBox) and name it "ListType", it is then automatically binded to the property in the viewModel.

My question, however, is: how do I then bind this non-visual property in the view with the property in the viewModel (and avoiding, if possible, creating dependencies between them, etc)? Can I do it somehow taking advantage of Caliburn.micro? If not, how would it be done directly in code (I am also trying out creating a new Binding and doing a SetBinding but with no success either)?

Thanks in advance for all input.
Aug 21, 2013 at 8:34 AM
Your dependency property is part of the visual tree. The fact is that CM binds together properly named controls and one or more properties, given a convention (e.g. a textbox named 'message' and a string property named 'message' will be wired together, so that the textbox.text is bound to the property value).
In your case, you need a specific convention for controls of type SelectionListView. Check the documentation about how to create such custom conventions.
Aug 29, 2013 at 12:14 AM
Hi again.

Thanks for your reply, BladeWise. However, I am still trying to get my head around this... or it is not true that my dependency property, as defined, is part of the visual tree. Let me explain further and with a different, simpler example.

I have gone back to my HelloWorld example with Caliburn.micro, as described in

Ok, in this very simple application, I was trying to accomplish exactly what I asked in my post: automatic (through Caliburn.micro) binding of a dependency property in my view with a property in my view model. Forget for a minute about "manually" declared dependency properties of a basic type, like what I mentioned in my first post... so I understand how Caliburn.micro is working in the background, I am now just trying to automatically bind a UI control in the view with the view model.

Let's say I want to add a new control in my HelloWorld application, it is a TextBlock and I want to bind it to a property in my view. Very simple then, in my XAML for the view I add:

<TextBlock Name="ListType" Visibility="Collapsed"/>

... and in the view model I have a corresponding property:
    string listType;
    public string ListType
        get { return listType; }
            listType = value;
            NotifyOfPropertyChange(() => ListType);
When I run this, everything works perfectly, the control in my view is binded to that property in the view model and when I change either one, the other updates. Then, how to achieve the same result when creating the UI control in your code behind file? (I ask this as a simpler, previous step to understanding how to bind dependency properties of basic types). Again, what I mean is REMOVING this line from my XAML:

<TextBlock Name="ListType" Visibility="Collapsed"/>

... and try to achieve the same automatic binding through Caliburn.micro but by manually defining that control in my view's code behind file. Here is the code:
    internal TextBlock ListType;

    public ShellView()

        // Add new TextBlock to the visual tree
        ListType = new TextBlock {Visibility = Visibility.Collapsed, Name = "ListType"};
... where MyStackPanel is the name of my main stack panel in the view. Well, this actually does work exactly as if I had defined the TextBlock in the XAML file, but it does not work if I comment out the line MyStackPanel.Children.Add(ListType);

Therefore, this leads me to believe that, as Caliburn.micro documentation mentions, only elements of the visual tree are automatically searched for binding (and that line is actually including that new TextBlock in the visual tree of the view). So my question remains then: is it possible then to make use of Caliburn.micro wiring of the binding for non-visual dependency properties in my view?


Sep 5, 2013 at 12:25 PM
Edited Sep 5, 2013 at 12:26 PM
how to achieve the same result when creating the UI control in your code behind file?
It depends on when the control is created: if you are able to generate the control before CM binds the view and the view-model together, you don't need any extra steps. If your view gets modified after being bound to the view-model, you need to force CM perform the binding operation (in other words, you need to call ViewModelBinder.Bind(viewModel, view, context)). Note that when I say view, I mean the complete control that was associated to a view-model, not just the control that was added dynamically.
Now, the fact that the binding does not happen unless you add the user control to the visual tree is no surprise: CM navigates the visual tree and uses name scopes to try to retrieve actual controls to be associated to properties. Nnote that I say 'controls', and not dependency properties... CM binds controls defined in the view, with properties defined in the view-model (and even events to functions).
is it possible then to make use of Caliburn.micro wiring of the binding for non-visual dependency properties in my view?
I think you mean 'is it possible to perform an automatic binding for controls that have not been attached to the visual tree'?
The short answer is: no. Unless CM is able to locate the control in a view name scope, such control will not be eligible to be automatically bound.
Long answer: there could be a possibility hacking with name scopes, so taht CM is able to locate a control outside of the visual tree, but in such a case, I fear you could find quite a lot of problems, due to the fact that bindings rely on the logical/inheritance tree that is often derived from the visual tree...

That said, your issue has nothing to do with this concepts.
In the first post, you are trying to bind a custom dependency property (defined in a view) to a view-model, while the above discussion is about trying to use CM with controls outside of the visual tree.
For your original purpose, as stated above, you need a custom convention.

Let me be clearer: CM knows that binding a view with a TextBlock called 'Surname' to a view-model having property named 'Surname', means create a binding between the TextBlock.Text property and the view-model 'Surname' property. This is a convention.
In your original example, you have defined a view with a custom property: CM knows nothing about your ListType dependency property, because it has no convention defined for the type SelectionListView. The ConventionManager is used to instruct CM binding engine, and allow for more complex binding scenarios, on a per-(UIElement-)type basis.
Dec 3, 2013 at 4:01 PM
Edited Dec 3, 2013 at 4:03 PM
public MyView()
    // This is the binding, which binds the property of the VM
    // to your dep. property.
    // My convention is give my property wrapper in the view the same
    // name as the property in the VM has.
    var nameOfPropertyInVm = "ViewModelString"
    var binding = new Binding(nameOfPropertyInVm) { Mode = BindingMode.TwoWay };
    this.SetBinding(SearchStringProperty, binding); // SearchStringProperty is dp defined in View
From stackoverflow

Eventually!! I found it!