Laden...

LookupConverter - Wpf

Erstellt von ErfinderDesRades vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.184 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 13 Jahren
LookupConverter - Wpf

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 ImageSources 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 Datagrids. 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 Enums 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.