How to bind to a Flag variable to a Xceed CheckComboBox - wpf

Given an object with a flag variable:
[Flags]
public enum fCondition
{
Scuffed = 1,
Torn = 2,
Stained = 4
}
public class AnEntity : TableEntity, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public int ConditionID { get; set; }
public fCondition Condition
{
get => (fCondition)ConditionID;
set {
if (value != (fCondition)this.ConditionID)
{
this.ConditionID = (int)value;
NotifyPropertyChanged();
}
}
}
}
An ObjectDataProvider to access the Flags
<ObjectDataProvider x:Key="enmCondition" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enm:fCondition"></x:Type>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
And the Xceed CheckComboBox
<xctk:CheckComboBox ItemsSource="{Binding Source={StaticResource enmCondition}}" />
At this stage it is showing the list of Flags with the check box.
I would have assumed that I would need to:
SelectedItemsOverride="{Binding Path=Condition, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
I have tried what seems to me to be all other logical combinations (not to metion some ones that seem illogical too, any help would be appreciated).

How are you supposed to bind several checked items to a single Condition property? You can't.
SelectedItemsOverride should be bound to an IList source property:
public List<fCondition> SelectedConditions { get; } = new List<fCondition>();
XAML:
<xctk:CheckComboBox ItemsSource="{Binding Source={StaticResource enmCondition}}"
SelectedItemsOverride="{Binding SelectedConditions}" />
If you only want to select a single value, you should use an ordinary ComboBox:
<ComboBox ItemsSource="{Binding Source={StaticResource enmCondition}}"
SelectedItem="{Binding Condition}" />

Related

WPF combobox with bound selected value and static items not recognizing selection on init

I need to have a combobox with two values. The first should have a custom name, while the second should use the underlying bound object's properties. Both items are values on the VM, and I'm able to bind all of it successfully.
XAML
<Window x:Class="StaticComboBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StaticComboBox"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:StaticUIVm}"
Title="MainWindow"
Height="450"
Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox Grid.Row="1"
SelectedValuePath="Tag"
SelectedValue="{Binding SelectedValue, Mode=TwoWay}">
<ComboBox.Items>
<ComboBoxItem Content="Custom Display Text 111"
Tag="{Binding FirstValue}" />
<ComboBoxItem Content="{Binding SecondValue.Item2}"
Tag="{Binding SecondValue}" />
</ComboBox.Items>
</ComboBox>
</Grid>
</Window>
XAML.cs
using System.Windows;
namespace StaticComboBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new StaticUIVm();
}
}
}
StaticUIVm.cs
using StaticComboBox.Annotations;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace StaticComboBox
{
public class StaticUIVm : INotifyPropertyChanged
{
public Tuple<long, string> FirstValue { get; set; }
public Tuple<long, string> SecondValue { get; set; }
private Tuple<long, string> _selectedValue;
public Tuple<long, string> SelectedValue
{
get { return _selectedValue; }
set
{
_selectedValue = value;
OnPropertyChanged();
}
}
public StaticUIVm()
{
FirstValue = new Tuple<long, string>(1, "Some Static Value");
SecondValue = new Tuple<long, string>(2, "Some Other Static Value");
SelectedValue = FirstValue;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
My problem is that despite the bindings working correctly for the items and displaying and when I as a user select a value, the combobox isn't reflecting the correct selection when initializing the VM class. Meaning, it doesn't select FirstValue. This doesn't make sense to me as the reference should be exactly the same, and I've confirmed that the value is in fact changing on the VM during initialization. I've definitely initialized values in the constructor and had them respected and displayed on load, so I'm a little confused as to where I'm going wrong here.
EDIT
I've accepted mm8's answer, but had to make a few additional tweaks to the XAML to get it to behave as needed. I needed to be able to trigger the custom text based on the ID value of the items, which was set at run time. Because of this a simple DataTrigger would not work so I had to use a MultiBinding. The MultiBinding broke the display when an item was selected (as described in ComboBox.ItemTemplate not displaying selection properly) so I had to set IsEditable to false. The full combobox is below.
<ComboBox Grid.Row="2"
Grid.Column="1"
IsEditable="False"
ItemsSource="{Binding ItemSource}"
SelectedItem="{Binding SelectedValue}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text"
Value="{Binding Name}" />
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource LongEqualToLongMultiBindingDisplayConverter}">
<Binding Path="Id" />
<Binding Path="DataContext.FirstValue.Id" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Text"
Value="Custom Display Text 111" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This XAML in combination with the suggestions from mm8's answer (setting up a collection which is initialized at runtime from the two provided values) did the trick.
Why don't you simply expose a collection of selectable items from your view model? This is how to solve this using MVVM:
public class StaticUIVm : INotifyPropertyChanged
{
public Tuple<long, string> FirstValue { get; set; }
public Tuple<long, string> SecondValue { get; set; }
private Tuple<long, string> _selectedValue;
public Tuple<long, string> SelectedValue
{
get { return _selectedValue; }
set
{
_selectedValue = value;
OnPropertyChanged();
}
}
public IEnumerable<Tuple<long, string>> Values { get; }
public StaticUIVm()
{
FirstValue = new Tuple<long, string>(1, "Some Static Value");
SecondValue = new Tuple<long, string>(2, "Some Other Static Value");
Values = new Tuple<long, string>[2] { FirstValue, SecondValue };
SelectedValue = SecondValue;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML:
<ComboBox x:Name="cmb" Grid.Row="1" ItemsSource="{Binding Values}"
SelectedItem="{Binding SelectedValue}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Item2}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Item1}" Value="1">
<Setter Property="Text" Value="Custom Display Text 111" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
You might even remove the FirstValue and SecondValue properties. The custom text is defined in the view but the actual options to choose from is defined in the view model.
MAJOR EDITS:
So when I first added an answer, I was trying to use what you already had instead of demonstrating how I would do it. WPF is both flexible and constrictive in certain ways and I have often found myself working around problems. Your question is actually quite simple when done using a different approach. Many of my programs have ComboBox controls and although I normally populate with a collection, a similar principle can be applied by using a helper data class over a Tuple. This will add significantly more flexibility and be more robust.
I added the property SelectedIndex and bound it to an int in your datacontext class. I also changed SelectedValue to SelectedItem as it it far superior in this use case.
<ComboBox Grid.Row="1"
SelectedValuePath="Tag"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
<ComboBox.Items>
<ComboBoxItem Content="{Binding FirstValue.display}"
Tag="{Binding FirstValue}" />
<ComboBoxItem Content="{Binding SecondValue.display}"
Tag="{Binding SecondValue}" />
</ComboBox.Items>
</ComboBox>
Datacontext Class, Data Class, and Extension Method:
So, I moved your property changed event over to a separate class. I recommend doing this as it makes it reusable. It is especially handy for the Data Class. Now in the constructor we set the selected item AND the selected index.
public class StaticUIVm : PropertyChangeHelper
{
private ComboBoxDataType _FirstValue;
public ComboBoxDataType FirstValue
{
get { return _FirstValue; }
set
{
_FirstValue = value;
OnPropertyChanged();
}
}
private ComboBoxDataType _SecondValue { get; set; }
public ComboBoxDataType SecondValue
{
get { return _SecondValue; }
set
{
_SecondValue = value;
OnPropertyChanged();
}
}
private ComboBoxDataType _SelectedItem;
public ComboBoxDataType SelectedItem
{
get { return _SelectedItem; }
set
{
_SelectedItem = value;
OnPropertyChanged();
}
}
private int _SelectedIndex;
public int SelectedIndex
{
get { return _SelectedIndex; }
set
{
_SelectedIndex = value;
OnPropertyChanged();
}
}
public StaticUIVm(string dynamicName)
{
FirstValue = new ComboBoxDataType() { id = 1, data = "Some Static Value", display = "Custom Display Text 111", };
SecondValue = new ComboBoxDataType() { id = 2, data = dynamicName, display = dynamicName, };
SelectedItem = FirstValue;
SelectedIndex = 0;
}
}
public class ComboBoxDataType : PropertyChangeHelper
{
private long _id { get; set; }
public long id
{
get { return _id; }
set
{
_id = value;
OnPropertyChanged();
}
}
private string _data { get; set; }
public string data
{
get { return _data; }
set
{
_data = value;
OnPropertyChanged();
}
}
private string _display { get; set; }
public string display
{
get { return _display; }
set
{
_display = value;
OnPropertyChanged();
}
}
}
public class PropertyChangeHelper : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
The reason for all of this you might ask...well this adds for flexibility instead of "hacking" things or adding in extra complexity in the XAML with a data trigger. You are working purely off of logic using an easy to manipulate data class.

wpf binding combobox to observable collection

I have an ObservableCollection that gets it's data from a DataTable that is populate from a Postgres Database. I need to bind this ObservableCollection to a ComboBoxColumn in a DataGrid. I have seen quite a lot of examples on how to do this, yet I'm constantly missing something.
Edit: This is the new updated code and it is working except for the INotifyPropertyChanged that I have set only to "name" (yet)
namespace Country_namespace
{
public class CountryList : ObservableCollection<CountryName>
{
public CountryList():base()
{
// Make the DataTables and fill them
foreach(DataRow row in country.Rows)
{
Add(new CountryName((string)row.ItemArray[1], (int)row.ItemArray[0]));
}
}
}
public class CountryName: INotifyPropertyChanged
{
private string name;
private int id_country;
public event PropertyChangedEventHandler PropertyChanged;
public CountryName(string country_name, int id)
{
this.name = country_name;
this.id_country = id;
}
public string Name
{
get { return name; }
set {
name = value;
OnPropertyChanged("CountryName");
}
}
public int idcountry
{
get { return id_country; }
set { id_country = value; }
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
XAML:
xmlns:c="clr-namespace:Country_namespace"
<Windows.Resources>
<c:CountryList x:Key="CountryListData"/>
</Windows.Resources>
DataGrid Column:
<dg:DataGridTemplateColumn Header="country">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource CountryListData}}" DisplayMemberPath="Name"></ComboBox>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
first of all. you can just bind to public properties.
country_ seems no public property.
second if binding not work you always have to check datacontext first and binding path second. you can use Snoop to do this at runtime
EDIT:
you did not post your itemssource for your grid. so some assumptions here.
<DataGrid ItemsSource="{Binding MySource}">
...
<ComboBox ItemsSource="{Binding MySourcePropertyForCountries}"/>
--> this would work when your MySource object item has a public property MySourcePropertyForCountries.
but if your want to bind your combobox to a list wich is outside the MySource object. then you have to use some kind relativeSourcebinding or elementbinding.
<DataGrid x:Name="grd" ItemsSource="{Binding MySource}">
...
<ComboBox ItemsSource="{Binding ElementName=grd, Path=DataContext.MyCountries}"/>
--> this would work when the datacontext of the datagrid has a property MyCountries

TwoWay Binding of a ComboBox to a static property

-------EDIT------
So, i figured that my code is correct and so are the code snippets from all of your answers. Thanks for that. My problem is that my dev-maschine runs .NET4.5 which behaves differently! The very same program (compiled against .NET4.0) runs correct on a maschine with .NET4.0 but not on a maschine with .NET4.5!
So here is my revised question.
-------EDIT------
First, the simple example how i two-way bind my combobox to my data context:
View model:
public class MainWindowViewModel
{
public List<String> MyElements { get; set; }
public string SelectedElement { get; set; }
public MainWindowViewModel()
{
MyElements = new List<string>() {"a", "b", "c"};
SelectedElement = "a";
}
}
and code-behind
private readonly MainWindowViewModel _viewModel = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
and my xaml
<ComboBox
ItemsSource="{Binding MyElements, Mode=OneWay}"
SelectedItem="{Binding SelectedElement}" />
This works fine and if i select an item whith the combobox, it is bound to my view model.
OK, now i want to make my viewModel static but still two-way bind the selectedItem. I try this:
public class MainWindowViewModel
{
public static List<String> MyElements { get; set; }
public static string SelectedElement { get; set; }
static MainWindowViewModel()
{
MyElements = new List<string>() {"a", "b", "c"};
SelectedElement = "a";
}
}
I do not need to set the datacontext in the Code-behind anymore and i know, that xaml needs an instance for two-way binding, so i have still the default constructor. I then bind the combobox
<Window.Resources>
<me:MainWindowViewModel x:Key="model"/>
</Window.Resources>
<StackPanel>
<ComboBox
ItemsSource="{Binding Source={x:Static me:MainWindowViewModel.MyElements}, Mode=OneWay}"
SelectedItem="{Binding Source={StaticResource model}, Path=SelectedElement}" />
</StackPanel>
The initial value is properly bound, but if i select another item with the combobox it it not reflected in my viewModel. What am i doing wrong?
EDIT:
If I use the exact same binding string for a TextBox and change the text in the box, it is reflected in the property.
<TextBox Text="{Binding Source={StaticResource model}, Path=SelectedElement}"/>
So obviously my binding string is correct but the way i use the combobox seems to be wrong. I also tried to bind SelectedValue instead... no change either.
Checked just in a sample project, works fine
public class ViewModel
{
static ViewModel()
{
Items=new ObservableCollection<string>();
SelectedItem = "222";
Items.Add("111");
Items.Add("222");
Items.Add("333");
Items.Add("444");
Items.Add("555");
}
private static string _selectedItem;
public static string SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value;
MessageBox.Show("Item " + value + " was selected");
}
}
private static ObservableCollection<string> _items;
public static ObservableCollection<string> Items
{
get { return _items; }
set { _items = value; }
}
}
and xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:WpfApplication1"
Title="MainWindow" Height="200" Width="300">
<Grid>
<Grid.Resources>
<my:ViewModel x:Key="viewM"/>
</Grid.Resources>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="101,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="146"
ItemsSource="{Binding Source={x:Static my:ViewModel.Items}, Mode=OneWay}"
SelectedItem="{Binding Source={StaticResource viewM}, Path=SelectedItem}" />
</Grid>
</Window>
I have uploaded sample.
You're being confused between instances and static properties: you don't need to bind a static object.
<ComboBox
ItemsSource="{x:Static me:MainWindowViewModel.MyElements}"
SelectedItem="{x:Static me:MainWindowViewModel.SelectedElement}" />
And you should implement INotifyPropertyChanged nevertheless.
Binding is about resolving the right instance from which you want to fetch data.
If there is no meaning of instance, there is no need for binding.

WPF : Get particular field from ObservableCollection

I have an ObservableCollection named SeiveList. I want all the SeiveIdSize from the list (except the last one as it is of no use) and set the DataContext for a Combobox. I added
seiveCmb.DataContext = GlobalUtils.SeiveList;
seiveCmb.DisplayMemberPath = // WHAT SHOULD GO HERE. hOW TO ONLY SHOW SeiveIdSize
// XML
<ComboBox Name="seiveCmb" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="1" Margin="2" SelectedIndex="0" ></ComboBox>
EDITED AS PER Sebastian's suggestion : At present, I just tried out with list for combobox.
My Seive class :
public class Seive : INotifyPropertyChanged
{
// Other Members
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string p)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(p));
}
}
In my Window .xaml file :
<Window.Resources>
<CollectionViewSource Source="{Binding Path=comboSeives}"
x:Key="comboSeivesFiltered"
Filter="ComboSeiveFilter">
</CollectionViewSource>
</Window.Resources>
<ComboBox Name="seiveCmb" ItemsSource="{Binding Source={StaticResource comboSeivesFiltered}}" DisplayMemberPath="SeiveIdSize"
Grid.Column="1" Grid.Row="1" Margin="2" SelectedIndex="0"
></ComboBox>
In Window .cs file :
public ObservableCollection<Seive> comboSeives { get; set; }
// Initial original data in Window_Loaded method
comboSeives = GlobalUtils.SeiveList;
public void ComboSeiveFilter(object sender, FilterEventArgs e)
{
Seive sv = e.Item as Seive;
// Add items those is != "TOTAL" and isSelected == false
if (sv.SeiveIdSize != "TOTAL" && sv.IsSelected == false)
e.Accepted = true;
else
e.Accepted = false;
}
If the id is "TOTAL" or isSelected is false (i.e. not added to the grid), then only return true and it will add up in it. With initial all records have isSelected = false.
This is what I have understood from youe explaination and help of this site. and have implemetned this. But in the runtime, I don't see any thing in the combobox. I tried to debug adding break at filter method, but it is never reached there. Can you point out where I am making mistake from the above code.
aNY HELP IS Appreciated.
Thanks
I understand that you want your Collection to be filtered, removing one element. One way to do this is create a CollectionView in your Window.Resources and apply a filter Method - as demonstrated and explained here.
<Window.Resources>
<CollectionViewSource Source="{Binding Path=SeiveList}"
x:Name="seiveListFiltered"
Filter="MyFilter">
</CollectionViewSource>
</Window.Resources>
Your code insinuates that in your case the collection is the DataContext of the Window. This must be changed to match your new Resource:
<ComboBox ItemsSource="{Binding Source={StaticResource seiveListFiltered}}"/>
Note that this will fill your ComboBox with items that resemble the output of your SeiveItem.ToString()-Method (Actually, I don't know the class name of the Item). Use the DisplayMemeberPath-Property to set the name of the Property to display instead.
<ComboBox DisplayMemberPath="SeiveIdSize" ItemsSource="{Binding Source={StaticResource seiveListFiltered}}"/>

ComboBox wpf not item not being selected

I am trying to bind a combo box to a list of objects, and it works great, besides the selected value, am I missing somethign?
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedValue="{Binding OrderInfoVm.BillingCountry}" />
Basically I want to bind value to country codes and set the selected value to the country code bound to OrderInfoVm.BillingCountry (which implements INotifyPropertyChanged)
Initially when the control loads selected value is empty, but on click BillingCountry is populated. Selected value does not seem to change. How can I remedy that?
I do agree with Alex that using SelectedItem gives the desired behaviour. See the code below. It works and will hopefully help you further:
<Window x:Class="SelectedValueSpike.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<StackPanel>
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedItem="{Binding OrderInfoVm.BillingCountry}"
IsSynchronizedWithCurrentItem="True"
Name="AllCountriesBox"/>
<TextBox Text="{Binding ElementName=AllCountriesBox, Path=SelectedValue}"/>
<Button>
Change the textbox to "Ca","NL",or "US" and click!
</Button>
</StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace SelectedValueSpike
{
public partial class Window1 : Window
{
public OrderInfoVm OrderInfoVm{ get; set;}
public Window1()
{
InitializeComponent();
OrderInfoVm=new OrderInfoVm();
OrderInfoVm.AllCountries.Add(new Country("US","US of A"));
OrderInfoVm.AllCountries.Add(new Country("NL","Netherlands"));
OrderInfoVm.AllCountries.Add(new Country("Ca","Canada"));
OrderInfoVm.BillingCountry = OrderInfoVm.AllCountries[1];
DataContext = this;
}
}
public class OrderInfoVm:INotifyPropertyChanged
{
public OrderInfoVm()
{
AllCountries=new ObservableCollection<Country>();
}
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Country> _allCountries;
public ObservableCollection<Country> AllCountries
{
get { return _allCountries; }
set
{
_allCountries = value;
OnPropertyChanged("AllCountries");
}
}
private Country _billingCountry;
public Country BillingCountry
{
get { return _billingCountry; }
set
{
_billingCountry = value;
OnPropertyChanged("BillingCountry");
}
}
private void OnPropertyChanged(string property)
{
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs(property));
}
}
public class Country
{
public string country_code { get; set; }
public string country_name { get; set; }
public Country(string code, string name)
{
country_code = code;
country_name = name;
}
}
}
Maybe you are trying to implement something similar to this: Bound ComboBox
Try changing it to SelectedItem and set Mode=TwoWay...
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedItem="{Binding OrderInfoVm.BillingCountry, Mode=TwoWay}" />
Edit: You may not need to change it to SelectedItem, perhaps just setting TwoWay will work, but that is how I've done it in my own code.
Please ensure that you've specified correct binding path.
Try starting project in debug mode and look at the output window to see if there are any binding errors
Give this a shot; I believe you have your SelectedValuePath and SelectedValue mixed up:
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValue="country_code"
DisplayMemberPath="country_name"
SelectedValuePath="{Binding OrderInfoVm.BillingCountry}" />
For Reference:
ItemsSource = Gets or sets a collection used to generate the content of the ItemsControl (ComboBox).
SelectedValue = Gets or sets the value of the SelectedItem, obtained by using SelectedValuePath.
SelectedValuePath = Gets or sets a value that indicates the path used to get the SelectedValue from the SelectedItem.
DisplayMemberPath = Gets or sets a path to a value on the source object to serve as the visual representation of the object.

Resources