Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 526 Vote(s) - 3.51 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to bind an enum to a combobox control in WPF?

#1
I am trying to find a simple example where the enums are shown as is. All examples I have seen tries to add nice looking display strings but I don't want that complexity.

Basically I have a class that holds all the properties that I bind, by first setting the DataContext to this class, and then specifying the binding like this in the xaml file:

<ComboBox ItemsSource="{Binding Path=EffectStyle}"/>

But this doesn't show the enum values in the `ComboBox` as items.
Reply

#2
You'll need to create an array of the values in the enum, which can be created by calling [System.Enum.GetValues()][1], passing it the `Type` of the enum that you want the items of.

If you specify this for the `ItemsSource` property, then it should be populated with all of the enum's values. You probably want to bind `SelectedItem` to `EffectStyle` (assuming it is a property of the same enum, and contains the current value).


[1]:

[To see links please register here]

Reply

#3
I used another solution using MarkupExtension.

1. I made class which provides items source:

public class EnumToItemsSource : MarkupExtension
{
private readonly Type _type;

public EnumToItemsSource(Type type)
{
_type = type;
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return Enum.GetValues(_type)
.Cast<object>()
.Select(e => new { Value = (int)e, DisplayName = e.ToString() });
}
}

2. That's almost all... Now use it in XAML:

<ComboBox DisplayMemberPath="DisplayName"
ItemsSource="{persons:EnumToItemsSource {x:Type enums:States}}"
SelectedValue="{Binding Path=WhereEverYouWant}"
SelectedValuePath="Value" />

3. Change 'enums:States' to your enum
Reply

#4
If you are binding to an actual enum property on your ViewModel, not a int representation of an enum, things get tricky. I found it is necessary to bind to the string representation, NOT the int value as is expected in all of the above examples.

You can tell if this is the case by binding a simple textbox to the property you want to bind to on your ViewModel. If it shows text, bind to the string. If it shows a number, bind to the value. Note I have used Display twice which would normally be an error, but it's the only way it works.

<ComboBox SelectedValue="{Binding ElementMap.EdiDataType, Mode=TwoWay}"
DisplayMemberPath="Display"
SelectedValuePath="Display"
ItemsSource="{Binding Source={core:EnumToItemsSource {x:Type edi:EdiDataType}}}" />

Greg
Reply

#5
All the above posts have missed a simple trick. It is possible from the binding of SelectedValue to find out how to populate the ItemsSource AUTOMAGICALLY so that your XAML markup is just.

<Controls:EnumComboBox SelectedValue="{Binding Fool}"/>


For example in my ViewModel I have

public enum FoolEnum
{
AAA, BBB, CCC, DDD

};


FoolEnum _Fool;
public FoolEnum Fool
{
get { return _Fool; }
set { ValidateRaiseAndSetIfChanged(ref _Fool, value); }
}

ValidateRaiseAndSetIfChanged is my INPC hook. Yours may differ.

The implementation of EnumComboBox is as follows but first I'll need a little helper to get my enumeration strings and values

public static List<Tuple<object, string, int>> EnumToList(Type t)
{
return Enum
.GetValues(t)
.Cast<object>()
.Select(x=>Tuple.Create(x, x.ToString(), (int)x))
.ToList();
}

and the main class ( Note I'm using ReactiveUI for hooking property changes via WhenAny )

using ReactiveUI;
using ReactiveUI.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Documents;

namespace My.Controls
{
public class EnumComboBox : System.Windows.Controls.ComboBox
{
static EnumComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumComboBox), new FrameworkPropertyMetadata(typeof(EnumComboBox)));
}

protected override void OnInitialized( EventArgs e )
{
base.OnInitialized(e);

this.WhenAnyValue(p => p.SelectedValue)
.Where(p => p != null)
.Select(o => o.GetType())
.Where(t => t.IsEnum)
.DistinctUntilChanged()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(FillItems);
}

private void FillItems(Type enumType)
{
List<KeyValuePair<object, string>> values = new List<KeyValuePair<object,string>>();

foreach (var idx in EnumUtils.EnumToList(enumType))
{
values.Add(new KeyValuePair<object, string>(idx.Item1, idx.Item2));
}

this.ItemsSource = values.Select(o=>o.Key.ToString()).ToList();

UpdateLayout();
this.ItemsSource = values;
this.DisplayMemberPath = "Value";
this.SelectedValuePath = "Key";

}
}
}

You also need to set the style correctly in Generic.XAML or your box won't render anything and you will pull your hair out.

<Style TargetType="{x:Type local:EnumComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
</Style>

and that is that. This could obviously be extended to support i18n but would make the post longer.
Reply

#6
public class EnumItemsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!value.GetType().IsEnum)
return false;

var enumName = value.GetType();
var obj = Enum.Parse(enumName, value.ToString());

return System.Convert.ToInt32(obj);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Enum.ToObject(targetType, System.Convert.ToInt32(value));
}
}

You should extend Rogers and Greg's answer with such kind of Enum value converter, if you're binding straight to enum object model properties.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through