none
Button in einem DataGrid (ohne Template ???) RRS feed

  • Frage

  • Hallo Forum,

    in einem DataGrid habe ich verschiedene Button aber über ein Template. Der Button beinhalten zum ClickCommand auch noch die Row Nummer (über einen Converter). Das sieht dann so aus.

    Bei einem Button wäre ein Template OK, nun brauche ich aber mehrere Button's. Mit Template direkt im DataGrid wird das sehr schnell unübersichtlich. Es funktioniert zwar, ist aber nicht besonders schön die Lösung. 

    So sieht das ButtonTemplate dazu aus, für die Numerierung verwende ich einen Converter:

    <DataGridTemplateColumn x:Name="gColRowNum" Header="">
       <DataGridTemplateColumn.CellTemplate>
           <DataTemplate>
                <Button x:Name="btnOpenObject"
                        Command="{Binding Path=DataContext.ObjectClickedCommand,
                                  RelativeSource={RelativeSource FindAncestor,
                                   AncestorType={x:Type DataGrid}}}"
                        IsEnabled="True">
                        <StackPanel Orientation="Horizontal">
                            <Image Width="10"
                                          Height="10"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            <TextBlock x:Name="txtRowNumber">
                                <TextBlock.Text>
                                   <MultiBinding Converter="{StaticResource rowNumberConverter}">
                                      <Binding />
                                           <Binding RelativeSource="{RelativeSource FindAncestor, 
    AncestorType={x:Type DataGrid}}" /> </MultiBinding> </TextBlock.Text> </TextBlock> </StackPanel> </Button> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>

    Gibt es nun die Möglichkeit eine eigene Button Column auf Basis von "DataGridBoundColumn" zu erstellen ?? Ich denke das würde zum DataGrid auch besser passen und auch die Übersicht verbessern.

    Danke und Gruß
    Gerhard Ahrens



    Dienstag, 22. März 2016 14:46

Antworten

  • Hallo Gerhard,

    die Lösung über das Template ist wie ich finde schon eine der besten die möglich sind. Wenn dich der Template-Code an dieser Stelle stört, so kannst du das Template auch in die Resources deines Windows o.ä. verschieben und dem Template einen x:Key geben. Dann kannst du auf das Template aus Ressource zugreifen:

           <DataTemplate x:Key="MyTemplate">
                <Button x:Name="btnOpenObject"
                        Command="{Binding Path=DataContext.ObjectClickedCommand,
                                  RelativeSource={RelativeSource FindAncestor,
                                   AncestorType={x:Type DataGrid}}}"
                        IsEnabled="True">
                        <StackPanel Orientation="Horizontal">
                            <Image Width="10"
                                          Height="10"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            <TextBlock x:Name="txtRowNumber">
                                <TextBlock.Text>
                                   <MultiBinding Converter="{StaticResource rowNumberConverter}">
                                      <Binding />
                                           <Binding RelativeSource="{RelativeSource FindAncestor, 
                                                                    AncestorType={x:Type DataGrid}}" />
                                    </MultiBinding>
                                </TextBlock.Text>
                            </TextBlock>
                        </StackPanel>
                </Button>
           </DataTemplate>
    
    <DataGridTemplateColumn x:Name="gColRowNum" Header="" CellTemplate="{StaticResource MyTemplate}"/>

    Das Template kannst du auch in ein ResourceDictionary verschieben und dieses in der MergedDictionaries einbinden.

    Als eigenes Control sollte das aber auch kein Problem sein, Hierfür musst du eine Klasse von DataGridTemplateColumn ableiten und darin fest die CellTemplate-Eigenschaft mit deinem Template zuweisen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Dienstag, 22. März 2016 15:47
    Moderator

Alle Antworten

  • Hallo Gerhard,

    die Lösung über das Template ist wie ich finde schon eine der besten die möglich sind. Wenn dich der Template-Code an dieser Stelle stört, so kannst du das Template auch in die Resources deines Windows o.ä. verschieben und dem Template einen x:Key geben. Dann kannst du auf das Template aus Ressource zugreifen:

           <DataTemplate x:Key="MyTemplate">
                <Button x:Name="btnOpenObject"
                        Command="{Binding Path=DataContext.ObjectClickedCommand,
                                  RelativeSource={RelativeSource FindAncestor,
                                   AncestorType={x:Type DataGrid}}}"
                        IsEnabled="True">
                        <StackPanel Orientation="Horizontal">
                            <Image Width="10"
                                          Height="10"
                                          HorizontalAlignment="Center"
                                          VerticalAlignment="Center" />
                            <TextBlock x:Name="txtRowNumber">
                                <TextBlock.Text>
                                   <MultiBinding Converter="{StaticResource rowNumberConverter}">
                                      <Binding />
                                           <Binding RelativeSource="{RelativeSource FindAncestor, 
                                                                    AncestorType={x:Type DataGrid}}" />
                                    </MultiBinding>
                                </TextBlock.Text>
                            </TextBlock>
                        </StackPanel>
                </Button>
           </DataTemplate>
    
    <DataGridTemplateColumn x:Name="gColRowNum" Header="" CellTemplate="{StaticResource MyTemplate}"/>

    Das Template kannst du auch in ein ResourceDictionary verschieben und dieses in der MergedDictionaries einbinden.

    Als eigenes Control sollte das aber auch kein Problem sein, Hierfür musst du eine Klasse von DataGridTemplateColumn ableiten und darin fest die CellTemplate-Eigenschaft mit deinem Template zuweisen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Dienstag, 22. März 2016 15:47
    Moderator
  • Hallo Tom,

    danke für Deine schnelle Antwort. Ja das geht natürlich so. Benötige ich nun aber verschiedene Buttons im DataGrid müsste ich ja auch verschiedene Templates anlegen, da ich ja eventuell ein Bild drin haben will oder auch das der Button an verschiedene Commands gebunden sein soll.

    Hier dachte ich mir nun eine DataGridButtonColumn auf Basis von DataGridBoundColumn wäre hier nun eleganter. Ich hatte mal auf Basis von Norbert Eder mit ein DataGridDateTimeColumn gebaut. Allerdings hatte ich da auch keine Commands gebraucht. Dies war daher einfacher. Verwende ich nun im DataGridBoundColumn ein Template habe ich ja auch das Problem, das ich die Commands oder eine Image Zuweisung nicht variable halten kann oder etwa doch ??

    Gruß
    Gerhard Ahrens

    Mittwoch, 23. März 2016 08:08
  • Hi Gerhard,
    natürlich kannst Du die Buttons in der Button-Spalte sehr variabel gestalten. Die einfachste Möglichkeit ist das Binden unterschiedlicher Eigenschaften (Hintergrund, Bild usw.) an Werte des Datenobjektes mit zwischengeschaltetem Konverter. Außerdem kannst Du unterschiedliche Inhalte des Templates vorbereiten, die dann über entsprechenden Selector in Abhängigkeit von Inhalten des betreffenden Datenobjektes für die Anzeige in der entsprechenden Zeile ausgewählt werden.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Mittwoch, 23. März 2016 08:24
  • Hallo Peter,

    danke für den Hinweis zum Template Selector, da muß ich noch etwas dazu lernen. Template Selector hatte ich bisher noch nicht wirklich richtig verwendet.

    Danke und Gruß
    Gerhard

    Mittwoch, 23. März 2016 12:28