patterncsharpMinor
WPF Load boolean values in combobox
Viewed 0 times
booleanwpfloadvaluescombobox
Problem
I have a Combobox and I want to edit a boolean value.
My ViewModel:
And I prepare the data for the Combobox ItemsSource that:
Is it the approach correct? Is there any easier solution?
UPDATE:
Extract from my ViewModel code (you remember EnumItemsSource is ItemsSource for Combobox and TargetValue the Combobox selected item):
```
private void LookUpViewData()
{
var propertyInfo = _firstSelectedItem.GetType().GetProperty(TargetFieldDescription.fdBigViewColumnName);
if ((propertyInfo != null) && (propertyInfo.GetValue(_firstSelectedItem) != null))
{
if ((int) FieldDataType.ENum == TargetFieldDescription.fdDataType)
PrepareDataForEnumTemplate(propertyInfo);
if ((int) FieldDataType.Bit == TargetFieldDescription.fdDataType)
PrepareDataForBitTemplate(propertyInfo); // like EnumTemplate
else if ((int) FieldDataType.Time == TargetFieldDescription.fdDataType)
PrepareDataForTimeTemplate(propertyInfo);
else
PrepareDataForDefaultTemplate(propertyInfo);
}
else
TargetValue = String.E
My ViewModel:
///
/// Contains the ItemsSource for Enums
///
public List EnumItemsSource
{
get { return _enumItemsSource; }
set
{
_enumItemsSource = value;
OnPropertyChanged();
}
}
public class EnumItemObject
{
public int Id {get;set;}
public string Name {get;set;}
}And I prepare the data for the Combobox ItemsSource that:
///
/// Sets the value to the properties for the BitTemplate view. (similar with EnumTemplate)
///
/// a boolean property
private void PrepareDataForBitTemplate(PropertyInfo propertyInfo)
{
TargetValue = (int)propertyInfo.GetValue(_firstSelectedItem);
EnumItemsSource = new List();
EnumItemsSource.Add(new EnumItemObject() { Id = 0, Name = "Nein" });
EnumItemsSource.Add(new EnumItemObject() { Id = 1, Name = "Ja" });
}Is it the approach correct? Is there any easier solution?
UPDATE:
Extract from my ViewModel code (you remember EnumItemsSource is ItemsSource for Combobox and TargetValue the Combobox selected item):
```
private void LookUpViewData()
{
var propertyInfo = _firstSelectedItem.GetType().GetProperty(TargetFieldDescription.fdBigViewColumnName);
if ((propertyInfo != null) && (propertyInfo.GetValue(_firstSelectedItem) != null))
{
if ((int) FieldDataType.ENum == TargetFieldDescription.fdDataType)
PrepareDataForEnumTemplate(propertyInfo);
if ((int) FieldDataType.Bit == TargetFieldDescription.fdDataType)
PrepareDataForBitTemplate(propertyInfo); // like EnumTemplate
else if ((int) FieldDataType.Time == TargetFieldDescription.fdDataType)
PrepareDataForTimeTemplate(propertyInfo);
else
PrepareDataForDefaultTemplate(propertyInfo);
}
else
TargetValue = String.E
Solution
It's not clear where this
Before I move on to the corresponding XAML markup, a few observations:
Now, given that your ViewModel exposes the above
And the converters would look like this:
Of course this is overkill if all you want is the enum names in your dropdown list - but I tend to define a
If all you need is to display an enum value directly in the UI, then this will suffice:
PrepareDataForBitTemplate(PropertyInfo) method is located. Is it code-behind? Whatever it is, if the goal is to bind a ComboBox with some enum values, I would much rather keep it standard - meaning the DataContext of the ComboBox is the ViewModel of the containing Window or UserControl:public IEnumerable ViewModelEnumValues
{
get { return Enum.GetValues(typeof(SomeEnumType)).Cast(); }
}
private SomeEnumType _selectedEnumValue;
public SomeEnumType SelectedEnumValue
{
get { return _selectedEnumValue; }
set { _selectedEnumValue = value; NotifyPropertyChanged(() => SelectedEnumValue); }
}Before I move on to the corresponding XAML markup, a few observations:
- The ViewModel implementation derives from some
ViewModelBaseabstract class which implementsINotifyPropertyChangedand allows its derivatives to specify a property name in a strongly-typed way. I see your setter calls someOnPropertyChanged()method, but not how that method is able to notify the View that a specific property was changed.
- The name
Enumrefers to a specific language construct. Calling something "Enum" when that something is not an enum is rather confusing.
- I don't see why you're not using an actual
enumwhen the values you're trying to load are basically "Yes" and "No".
EnumItemObjectis an awful name, for several reasons:
- It's not an object, it's a class - an object is an instance of a class.
- It's not an enum item, it's essentially a ViewModel that exposes two properties - an
intand astring.
- It's not immediately apparent how this class relates to any type of enum.
Now, given that your ViewModel exposes the above
SelectedEnumValue and ViewModelEnumValues properties (both bad/stub names), with a ValueConverter the XAML for the ComboBox would be as simple as this:
And the converters would look like this:
using resx = Project.Properties.Resources;
public class EnumValueToStringConverter : ConverterBase
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
SomeEnumType result;
return Enum.TryParse(value.ToString(), out result)
? resx.ResourceManager.GetString(promoType + "Caption")
: string.Empty;
}
}
public class EnumValueToIconConverter : ConverterBase
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = string.Empty;
var typedValue = value As SomeEnumType;
if (typedValue != null)
{
switch(typedValue)
{
case SomeEnumType.EnumValue1:
result = "images/image-for-value1.png";
break;
case SomeEnumType.EnumValue2:
result = "images/image-for-value2.png";
break;
}
}
return new BitmapImage(new Uri("/project.namespace;component/" + result, UriKind.Relative));
}
}Of course this is overkill if all you want is the enum names in your dropdown list - but I tend to define a
DataTemplate for just about everything (and I think I have a tendency to abuse converters, too).If all you need is to display an enum value directly in the UI, then this will suffice:
public IEnumerable ViewModelEnumNames
{
get { return Enum.GetNames(typeof(SomeEnumType)).ToList(); }
}
private string _selectedEnumName;
public string SelectedEnumName
{
get { return _selectedEnumName; }
set { _selectedEnumName = value; NotifyPropertyChanged(() => SelectedEnumName); }
}Code Snippets
public IEnumerable<SomeEnumType> ViewModelEnumValues
{
get { return Enum.GetValues(typeof(SomeEnumType)).Cast<SomeEnumType>(); }
}
private SomeEnumType _selectedEnumValue;
public SomeEnumType SelectedEnumValue
{
get { return _selectedEnumValue; }
set { _selectedEnumValue = value; NotifyPropertyChanged(() => SelectedEnumValue); }
}<ComboBox ItemSource="{Binding ViewModelEnumValues}"
SelectedItem="{Binding SelectedEnumValue, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource ListItemBorder}"> <!-- just some border -->
<StackPanel>
<Image Source="{Binding Value, Converter={StaticResource EnumValueIconConverter}}" />
<Label Content="{Binding Value, Converter={StaticResource EnumValueNameConverter}}" />
</StackPanel>
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>using resx = Project.Properties.Resources;
public class EnumValueToStringConverter : ConverterBase
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
SomeEnumType result;
return Enum.TryParse(value.ToString(), out result)
? resx.ResourceManager.GetString(promoType + "Caption")
: string.Empty;
}
}
public class EnumValueToIconConverter : ConverterBase
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = string.Empty;
var typedValue = value As SomeEnumType;
if (typedValue != null)
{
switch(typedValue)
{
case SomeEnumType.EnumValue1:
result = "images/image-for-value1.png";
break;
case SomeEnumType.EnumValue2:
result = "images/image-for-value2.png";
break;
}
}
return new BitmapImage(new Uri("/project.namespace;component/" + result, UriKind.Relative));
}
}public IEnumerable<string> ViewModelEnumNames
{
get { return Enum.GetNames(typeof(SomeEnumType)).ToList(); }
}
private string _selectedEnumName;
public string SelectedEnumName
{
get { return _selectedEnumName; }
set { _selectedEnumName = value; NotifyPropertyChanged(() => SelectedEnumName); }
}<ComboBox ItemSource="{Binding ViewModelEnumNames}"
SelectedItem="{Binding SelectedEnumName, Mode=TwoWay}">Context
StackExchange Code Review Q#36255, answer score: 3
Revisions (0)
No revisions yet.