How to capture combobox selection in Caliburn Micro?
Asked Answered
M

2

24

I am just starting with Caliburn Micro. I want to have a combo box with a list of strings, and when the user selects an item, I want to have some notify method called. It should be simple, right? I am impatient, and 5 minutes of Googling has not solved it for me, so Stackers to the rescue!

Note: I favor an answer that shows me how to put this into the view model. Avoiding complex XAML is the whole point of a MVVM framework, IMHO.

Mozza answered 29/4, 2011 at 20:57 Comment(1)
Another rather elegant solution is proposed here: #4041733Valenevalenka
F
63

Caliburn.Micro has baked in conventions supporting ItemsControl (e.g. ComboBox or ListBox) based controls which make the required xaml in you View minimal.

First you have the standard convention where a controls content will be bound to a ViewModel property with the same name as the control. In the case of ItemsControl the controls content property is ItemsControl.ItemsSource. And the second convention you get out of the box with Caliburn.Micro is that an attempt will be made to bind ItemsControl.SelectedItem to a ViewModel property which has the singularized name of the control, with either "Active", "Selected" or "Current" prepended (see ConventionManager in the Caliburn.Micro source).

This in mind you can achieve what you want with the following in your View:

<ComboBox x:Name="Strings"></ComboBox>

and in your ViewModel:

public BindableCollection<string> Strings
{
    get
    { 
        // silly example of the collection to bind to
        return new BindableCollection<string>(
                         new string[]{ "one", "two", "three"});               
    }
}

private string _selectedString;
public string SelectedString
{
    get { return _selectedString; }
    set
    {
        _selectedString= value;
        NotifyOfPropertyChange(() => SelectedString);
        // and do anything else required on selection changed
    }
}

The first convention picks up the control name ("Strings") and binds ComboBox.ItemsSource to the ViewModel property Strings. The second convention first singularizes "Strings" to "String" and prepends "Selected" to get the property "SelectedString" to bind ComboBox.SelectedItem to.

Fidelity answered 2/5, 2011 at 5:14 Comment(2)
This should be the accepted answer here IMO. This gets rids of the nasty binding code in XAML that names the event function in the ViewModel, and relies on Caliburn.Micro's conventions like it should. +1 to you sir.Coven
This also allows the ViewModel to dictate the default values in the ViewModel constructor: SelectedString = Strings[1]; which is nicer than having the default values in XAML.Intussusception
S
12
<ListBox x:Name="Items" ItemsSource="{Binding Path=Items}" cal:Message.Attach="[Event SelectionChanged]=[Action SelectedItemChanged($this.SelectedItem)]">
Scirrhous answered 29/4, 2011 at 21:28 Comment(2)
That is alot of XAML to handle one event. I thought the point of Caliburn was to use convention to reduce all that clutter.Mozza
what is the definition of cal here?Mozza

© 2022 - 2024 — McMap. All rights reserved.