I want to show list of products in ListView
where one of the columns is a ComboBox
that I want to bind. This is my enum:
public enum SelectionMode { One, Two }
And Product class:
public class Product
{
public SelectionMode Mode { get; set; }
public string Name { get; set; }
}
In ViewModel
class I have an ObservableCollection
of Product
's:
private ObservableCollection<Product> _productList;
public ObservableCollection<Product> ProductList
{
get
{
return _productList;
}
set
{
_productList = value;
}
}
public MainViewModel()
{
ProductList = new ObservableCollection<Product>
{
new Product {Mode = SelectionMode.One, Name = "One"},
new Product {Mode = SelectionMode.One, Name = "One"},
new Product {Mode = SelectionMode.Two, Name = "Two"}
};
}
And finally I have a Grid
with a ListView
that binds to my ProductList
:
<Window.Resources>
<ObjectDataProvider x:Key="AlignmentValues"
MethodName="GetNames" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ViewModel:SelectionMode" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<ListView Height="120" HorizontalAlignment="Left"
VerticalAlignment="Top"
SelectionMode="Multiple"
ItemsSource="{Binding ProductList}" >
<ListView.View>
<GridView>
<GridViewColumn Width="120" Header="Product Name" DisplayMemberBinding="{Binding Path=Name}" />
<GridViewColumn Header="Selection Mode">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource AlignmentValues}}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
My question is; what is the way to bind SelectedValue
of ComboBox
to SelectionMode
property of my Product
class?
Update
Well. I found an answer in this topic. So I have to add converter class:
public class MyEnumToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (SelectionMode)Enum.Parse(typeof(SelectionMode), value.ToString(), true);
}
}
And add it to window resources:
<Window.Resources>
<ObjectDataProvider x:Key="AlignmentValues"
MethodName="GetNames" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="ViewModel:SelectionMode" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Converters:MyEnumToStringConverter x:Key="MyEnumConverter"/>
</Window.Resources>
And finally edit ComboBox
data template:
<ComboBox ItemsSource="{Binding Source={StaticResource AlignmentValues}}"
SelectedValue="{Binding Path=Mode, Converter={StaticResource MyEnumConverter}}"/>
That's all. Hope it will be useful for someone else :)
i'm using a Converter for this, which also allows to define a string that will be displayed instead of the enum value: http://www.ageektrapped.com/blog/the-missing-net-7-displaying-enums-in-wpf/
Heres my usage of binding enums to a list/combox
Here is my XAML
My View Model
and my convertors
In my personal opinion its alot cleaner and highly re-usable. The only flaw I've found so far with it is if you update the selected value in code(not via UI) then its not updating on the UI. But this can be overcome with some further UI tweaking. I'm doing the change now and I'll update this answer once I've completed it.
If you are ready to change the binding of the ItemsSource of the ComboBox then, simply
SelectedValue="{Binding Mode,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
will work.In this case you have to bind the ItemsSource like this:
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ViewClass}}, Path=ModeList}"
; where, the ModeList is a simple public property of list ofSelectionMode
type, contains the enums which should be displayed in ComboBox dropdown and ViewClass is the class where this property (ModeList) is a available; make sure the reference of the namespace is added in the xaml.Otherwise you have to use a converter, which should convertback the string to the enum type.