Question:
My problem is that I'm trying to bind between a ComboBox
and a string
property in the viewModel, but I can't do it
<ComboBox HorizontalAlignment="Stretch"
SelectedItem="{Binding Path=OResultado, Mode=TwoWay}">
<ComboBoxItem Content="Anomalia"/>
<ComboBoxItem Content="Retiro"/>
<ComboBoxItem Content="Retiro con Anomalia"/>
<ComboBoxItem Content="Conforme"/>
</ComboBox>
I tried with SelectedItem
and SelectedValue
, SelectedIndex
but it returns only the index of the selected ComboBoxItem
. I tried to make a Converter
but I couldn't get it to produce the expected result.
What I want to do is that when the user selects an item from the ComboBox
, the Content
value of the item is assigned to the string OResultado
of my viewModel.
Answer:
In this case there are several ways to do it, but the easiest way is to populate the ComboBox dynamically instead of with static values.
This is achieved by creating the list of options in the ViewModel
and Binding
with the ItemsSource
of the ComboBox
.
view model
you can get BindableBase here: Apps, Binding, INotifyPropertyChanged and BindableBase | XAML | C# , I have set the value of OResultado= "Conforme"
.
Additionally, I have performed the trick of lazy initialization with the call to the properties to be able to create the instance of the viewmodel
from the xaml
using App3.Util;
using System.Collections.ObjectModel;
namespace App3.ViewModels
{
public class MainAppVM : BindableBase
{
private bool _initialized = false;
private object _lockject = new object();
public ObservableCollection<string> _listaOpciones;
public ObservableCollection<string> ListaOpciones
{
get
{ Initialize();
return _listaOpciones;}
set { SetProperty(ref _listaOpciones, value); }
}
private string _oResultado;
public string OResultado
{
get
{ Initialize();
return _oResultado; }
set { SetProperty(ref _oResultado, value); }
}
public void Initialize()
{
lock (_lockject)
{
if (!_initialized)
{
_initialized = true;
_listaOpciones = new ObservableCollection<string>();
_listaOpciones.Add("Anomalia");
_listaOpciones.Add("Retiro");
_listaOpciones.Add("Retiro con Anomalia");
_listaOpciones.Add("Conforme");
_oResultado = "Conforme";
}
}
}
}
}
XAML
already having the viewModel then you add it in your xaml
as DataContext
<Page.DataContext>
<vm:MainAppVM/>
</Page.DataContext>
and then do binding of the ItemsSource
with ListaOpciones
which is the property exposed in the ViewModel, at once then you assign SelectedItem
to do binding with OResultado
in TwoWay Mode
<ComboBox x:Name="combo" HorizontalAlignment="Stretch" VerticalAlignment="Center"
ItemsSource="{Binding ListaOpciones}"
SelectedItem="{Binding OResultado, Mode=TwoWay}" >
</ComboBox>
Remember to add the reference to the viewmodel's namespace (line 5 ).
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:vm="using:App3.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="App3.MainPage"
mc:Ignorable="d">
<Page.DataContext>
<vm:MainAppVM/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<ComboBox x:Name="combo" HorizontalAlignment="Stretch" VerticalAlignment="Center"
ItemsSource="{Binding ListaOpciones}"
SelectedItem="{Binding OResultado, Mode=TwoWay}" >
</ComboBox>
</StackPanel>
</Grid>
</Page>
This is all!
And as I always tell you, you have to learn Binding, I recommend the