Bei einem meiner WPF-Projekte ergab sich die Problematik, das ich ein Enum an mehrere RadioButtons binden wollte. Nach recht langer Suche und einigen Versuchen habe ich einen Lösungsweg gefunden, den ich hier an einem kleinen Beispiel zeigen will. Den Source für den ValueConverter habe ich mir nicht ausgedacht. Beim googlen nach der Lösung habe ich durch Zufall diese Seite gefunden und den darauf befindlichen Source verwendet.
Ausgangspunkt ist einen kleine Klasse und ein Enum
public enum ProjectStatus { InVorbereitung, InArbeit, Abgeschlossen } public class Project { public string ProjectName { get; set; } public ProjectStatus Status { get; set; } }
Nun soll diese Klasse per Binding in einem WPF-Window dargestellt werden.
Dafür erstellen wir ein Exemplar der Klasse im Constructor des Windows und weise es dem DataContext zu:
Project project = new Project(); project.ProjectName = "RadioButton Binding Test"; project.Status = ProjectStatus.InArbeit; DataContext = project;
Und nun kann im Xaml alles entsprechend gebunden werden. Dabei sollen alle möglichen Enum-Werte als RadioButtons dargestellt werden. Hier das Formular ohne Werte: 
Hier der vollständige Xaml-Code
<Window x:Class="WPFRadioButtonBinding.frmMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:WPFRadioButtonBinding" Title="Binding" Height="150" Width="250"> <Window.Resources> <c:EnumBooleanConverter x:Key="enumBooleanConverter" /> </Window.Resources> <StackPanel> <Label Margin="2,0,0,0" Name="lblProjectName" VerticalAlignment="Top" HorizontalAlignment="Left" Content="ProjectName" /> <TextBox Margin="2,0,0,0" Name="txtProjectName" VerticalAlignment="Top" HorizontalAlignment="Left" Text="{Binding ProjectName}"/> <RadioButton Margin="2" Name="radInVorbereitung" VerticalAlignment="Top" HorizontalAlignment="Left" Content="InVorbereitung" IsChecked="{Binding Path=Status, Converter={StaticResource enumBooleanConverter}, ConverterParameter=InVorbereitung}"/> <RadioButton Margin="2" Name="radInArbeit" VerticalAlignment="Top" HorizontalAlignment="Left" Content="InArbeit" IsChecked="{Binding Path=Status, Converter={StaticResource enumBooleanConverter}, ConverterParameter=InArbeit}"/> <RadioButton Margin="2" HorizontalAlignment="Left" Name="radAbgeschlossen" VerticalAlignment="Top" Content="Abgeschlossen" IsChecked="{Binding Path=Status, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Abgeschlossen}"/> <TextBlock Margin="2" Name="txtStatus" VerticalAlignment="Bottom" Text="{Binding Status}" HorizontalAlignment="Left" /> </StackPanel> </Window>
Der Trick ist beim Binding des Enums an die RadioButtons. Hierfür wird ein ValueConverter verwendet, der per Parameter “gesagt” bekommt, um welchen Wert es sich handet. Der ValueConverter “entscheidet dann, on es sich um den richtigen Wert handelt oder auch nicht”:
IsChecked="{Binding Path=Status, Converter={StaticResource enumBooleanConverter}, ConverterParameter=InVorbereitung}"/>Hier noch der Source für den ValueConverter:
class EnumBooleanConverter : IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string ParameterString = parameter as string; if (ParameterString == null) { return DependencyProperty.UnsetValue; } if (Enum.IsDefined(value.GetType(), value) == false) { return DependencyProperty.UnsetValue; } object paramvalue = Enum.Parse(value.GetType(), ParameterString); if (paramvalue.Equals(value)) { return true; } else { return false; } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string ParameterString = parameter as string; if (ParameterString == null) { return DependencyProperty.UnsetValue; } return Enum.Parse(targetType, ParameterString); } #endregion }
Hier der vollständige Source (Visual Studio 2008): Download








Eine Reaktion
1. ich schrieb am 11th Februar 2009 um 12:26 :
Hi, Lars.
Hat mir sehr geholfen! Danke.
Allerdings wenn du mit der Datenbindung noch mitkriegen willst, ob auch die Auswahl geändert wurde…
Ist es hilfreich beim ConvertBack die letzte Zeile zu modifizieren…
return (bool) value ? Enum.Parse(targetType, ParameterString) : DependencyProperty.UnsetValue;Damit dann auch der richtige Wert deiner Enum-Eigenschaft an dein Objekt gebunden wird…
Grüße.
Leave a comment
Trackback URL | RSS feed for comments on this post.