LookupConverter
stellt eine Tabelle dar, in der in der ersten Spalte (Key-Spalte) gesucht wird, und das Ergebnis aus der 2.Spalte returnt. Über den ConverterParameter kann man auch andere Ergebnisspalten anfordern, Default-Einstellung ist aber die 2. Spalte.
Ich habe die IValueConverter-
Schnittstelle voll ausprogrammiert, also beim .ConvertBack()
suchter in der ErgebnisSpalte, und returnt die Entsprechung aus der Key-Spalte (nur weißichgrad keinen sinnvollen Einsatz für das Feature.)
Die Tabelle wird im Xaml angelegt, und man kann beliebige Sachen hineintun. Etwas hanebüchen ist, dass man die Tabelle Spaltenweise anlegt, also erst die erste Spalte komplett, dann die 2., dann ggfs. weitere.
Habe ich aber so gemacht, weil man so das einfachste Xaml schreiben kann, mit der geringstmöglichen Verschachtelung.
Wenn man nun in einer Ergebnisspalte weniger Elemente angelegt hat als in der Key-Spalte - isnich soo gut. Passiert aber auch nix schlimmes - gibterhalt null zurück.
Im Beispiel habe ich ein Datenmodell, wo frei editierbaren Inputs Aktionen zugeordnet werden können. Die Aktionen sind als Enum
dargestellt.
public enum Action { Hinlegen, Aufstehen, NaseBohren, Einschlafen }
public class ActionMapping {
public string Input { get; set; }
public Action Action { get; set; }
}
public class MainViewModel {
private ObservableCollection<ActionMapping> _Data =
new ObservableCollection<ActionMapping>(new ActionMapping[] {
new ActionMapping(){Input="Text1", Action=Action.Hinlegen},
new ActionMapping(){Input="Text2", Action=Action.Aufstehen},
new ActionMapping(){Input="Text3", Action=Action.NaseBohren},
new ActionMapping(){Input="Text4", Action=Action.Einschlafen}
});
public ObservableCollection<ActionMapping> Data { get { return _Data; } }
}
Im Gui hat man dann ein Datagrid
, wo man den Input in eine DatagridTextColumn
eingibt, und mit einer DatagridComboColumn
die Aktion aus den zulässigen Werten auswählt. Und damit schön bunt ist, werden die Aktionen mit Bildchen assoziiert, und hier kommt der LookupConverter
zum Einsatz:
Ich lege nämlich darin eine Tabelle von Aktionen und ImageSource
s an.
Und in der Combo habe ich ein DataTemplate
mit einem Image
und mit einem Textblock.
Der Textblock
wird nun an die Action-Property des Mappings gebunden und das Image
auch! - aber beim Image
wird der LookupConverter
dazugeschaltet, der die Action ja in eine ImageSource
konvertiert.
So komme ich zu schön bebilderten Combobox-Einträgen.
Auch bequem am LookupConverter
, dassichihn gleich als ItemsSource der Combo benutzen kann.
Das war bisher nur das EditingTemplate
der TemplateColumn
des Datagrid
s. Aber mittm CellTemplate
isses dasselbe Spielchen, das ist das praktische, dassich den LookupConverter
gleich nochmal verwenden kann.
Interessant ist auch, dassich den LookupConverter
nicht unbedingt mit allen Enum
s befüllen muß. So habe ich eine genaue Kontrolle, was der User anwählen kann, und was nicht.
<Window x:Class="LookupConverterTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:hlp="clr-namespace:System.Windows.Controls;assembly=Helpers"
xmlns:my="clr-namespace:LookupConverterTester"
DataContext="{Binding Source={StaticResource RootModel}, Path=Root}">
<Window.Resources>
<hlp:LookupConverter x:Key="Enum2Image">
<hlp:LookupConverterColumn>
<my:Action>Hinlegen</my:Action>
<my:Action>Aufstehen</my:Action>
<my:Action>NaseBohren</my:Action>
<!--<my:Action>Einschlafen</my:Action>-->
</hlp:LookupConverterColumn>
<hlp:LookupConverterColumn>
<ImageSource>/LookupConverterTester;component/Images/delete_16x.ico</ImageSource>
<ImageSource>/LookupConverterTester;component/Images/document.ico</ImageSource>
<ImageSource>/LookupConverterTester;component/Images/folderopen.ico</ImageSource>
<ImageSource>/LookupConverterTester;component/Images/error.ico</ImageSource>
</hlp:LookupConverterColumn>
</hlp:LookupConverter>
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding Path=Data}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Input" Binding="{Binding Path=Input}" />
<DataGridTemplateColumn Header="Action" >
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Path=Action}" Padding="0"
ItemsSource="{Binding Source={StaticResource Enum2Image}, Mode=OneTime, Path=Keys}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16"
Source="{Binding Converter={StaticResource Enum2Image}}" Margin="1,0,0,0" />
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="2,0,0,0"
Source="{Binding Path=Action, Converter={StaticResource Enum2Image}}"/>
<TextBlock Text="{Binding Path=Action}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Der frühe Apfel fängt den Wurm.