Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do caliburn.micro binding of view model to combobox selected value?

I'm relatively low on the curve for both WPF and Caliburn.Micro.

My goal here is to move the binding of the combobox selected item from the ShellView's code behind to the View Model, the same as it already is for the combobox's item collection.

XAML:

<Window x:Class="EomDatabaseUtility.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Eom Tool Database Utility" Height="350" Width="525">
    <Grid>
        <DataGrid AutoGenerateColumns="False" Height="258" HorizontalAlignment="Left" Margin="12,41,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="479" />
        <Button Content="Execute" Height="23" HorizontalAlignment="Left" Margin="416,12,0,0" VerticalAlignment="Top" Width="75" x:Name="Execute" />
        <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Width="120" x:Name="CatalogName" SelectedValuePath="{Binding Path=SelectedCatalogName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    </Grid>
</Window>

Code Behind (where the goal is to not have to add any code, if I uderstand correctly):

namespace EomDatabaseUtility.Views
{
    using System.Windows;

    public partial class ShellView : Window
    {
        public ShellView()
        {
            InitializeComponent();
        }

        // --> This should go in the view model, Right?
        private string selectedCatalogName;
        public string SelectedCatalogName
        {
            get { return selectedCatalogName; }
            set { selectedCatalogName = value; }
        }
    }
}

View Model (currently supplying the collection of items to the combobox as well as a button event handler):

namespace EomDatabaseUtility.ViewModels
{
    using Caliburn.Micro;
    using System.Collections.Generic;

    public class ShellViewModel : PropertyChangedBase
    {
        public List<string> CatalogName
        {
            get
            {
                return new List<string> { "foo", "bar" };
            }
        }

        public void Execute()
        {
            System.Windows.MessageBox.Show("hello");
        }
    }
}
like image 742
Aaron Anodide Avatar asked Mar 07 '12 20:03

Aaron Anodide


People also ask

How do I get the ComboBox selected value?

string strID = MyCombobox2. SelectedValue. ToString();

What is selected item in ComboBox?

When you set the SelectedItem property to an object, the ComboBox attempts to make that object the currently selected one in the list. If the object is found in the list, it is displayed in the edit portion of the ComboBox and the SelectedIndex property is set to the corresponding index.


1 Answers

You can bind the SelectedItem of the ComboBox to a property on your view model:

<ComboBox x:Name="CatalogName" ... SelectedItem="{Binding SelectedCatalog}" />

public class ShellViewModel : PropertyChangedBase
{
    private string selectedCatalog;

    public List<string> CatalogName
    {
        get
        {
            return new List<string> { "foo", "bar" };
        }
    }

    public string SelectedCatalog
    {
       get
       {
          return this.selectedCatalog;
       }

       set
       {
          this.selectedCatalog = value;
          this.NotifyOfPropertyChange(() => this.SelectedCatalog);
       }
    }

In fact, because your ComboBox has a name of CatalogName, the Caliburn.Micro conventions will look for a property called SelectedCatalogName (or ActiveCatalogName) and automatically bind the ComboBox's SelectedItem to that, so therefore you can use:

<ComboBox x:Name="CatalogName" ... />

public string SelectedCatalogName
{
  ...
}

A few things to note:

  • We call NotifyOfPropertyChange() in the setter for the SelectedCatalog. This notifies the UI that the value has changed whenever we set it from the view model, so that the UI gets updated. This method is part of PropertyChangedBase.
  • You should really use a collection type which supports collection changed notifications in your view models, such as ObservableCollection which comes with WPF, or Caliburn.Micro's BindableCollection (which implements Caliburn.Micro's IObservableCollection). This allows the UI to be notified when objects are added/removed from your collections from the view model.
  • Your shell view model should probably implement a Screen or Conductor type (rather than PropertyChangedBase) if it's going to have a life cycle (activation/deactivation etc), or going to have a currently active item (screen) which can change at run time.
like image 51
devdigital Avatar answered Oct 14 '22 07:10

devdigital