Laden...

[gelöst] DataGrid Template setzen -> DataGrid hat 0 Columns

Erstellt von 1nf1n1ty vor 13 Jahren Letzter Beitrag vor 13 Jahren 2.273 Views
1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren
[gelöst] DataGrid Template setzen -> DataGrid hat 0 Columns

Hallo zusammen,

für ein selbstgebautes Control verwende ich ein DataGrid und möchte dabei dem Entwickler die Wahl lassen welche Spalten das DataGrid haben soll. Mein Ziel war es, dass der Entwickler dann in der Template-Eigenschaft des Controls sein DataGrid Template reinpackt und die Tabelle dann so aussieht, wie er es definiert hat.

Das funktioniert soweit auch gut, jedoch verwende ich in der Klasse meines Controls verschiedene Funktionen um mit den Columns zu arbeiten. Wenn ich dem DataGrid nun ein Template zuweise ist die Anzahl meiner Spalten komischerweise immer 0, obwohl ich die Spalten sehen kann.

Das ganze lässt sich auch ohne Implementierung in meinem Control nachvollziehen.
Beispiel:


<ControlTemplate x:Key="dgTest" TargetType="sdk:DataGrid">
     <sdk:DataGrid>
         <sdk:DataGrid.Columns>
             <sdk:DataGridTextColumn Header="1" />
             <sdk:DataGridTextColumn Header="2" />
         </sdk:DataGrid.Columns>
     </sdk:DataGrid>
</ControlTemplate>

<sdk:DataGrid Template="{StaticResource dgTest}" x:Name="dg"/>

Woran liegt das bzw. was muss ich tun, damit ich wieder auf meine Columns zugreifen kann?

Vielen Dank für die Hilfe.

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

Woran liegt das bzw. was muss ich tun, damit ich wieder auf meine Columns zugreifen kann?

Woran das liegt kann ich dir sagen.
In deinem ControlTemplate definierst du ein neues DataGrid.
Damit sagst du folgendes: Mein DataGrid soll aussehen wie ein DataGrid mit X Columns.

Das mag zwar richtig klingen und auch funktionieren ist aber nicht wirklich optimal.
Denn du hast ein DataGrid in einem DataGrid

Wenn du nun auf die Columns zugreifst dann greifst du auf die des äusseren DataGrids zu. Diese gibt es natürlich nicht weil du nur die des Inneren gesetzt hast.

Ich würde von diesem Aufbau abstand nehmen und es auf eine andere Weise implementieren.
z.B. indem du mit einem Style die Columns des DataGrid setzst und nicht indem du das Template setzt.

Gruss
Michael

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren

Hi,

danke schonmal. Ok, das erklärt natürlich warum ich dann keine Spalten habe. Ich hatte das so verstanden, das hier das aussehen des Controls geändert werden kann. Ich konnte beim ControlTemplate auch die übergeordnete ItemsSource Property setzen und habe zumindest meine Ergebnisse gesehen. Ich dachte das wäre der richtige Weg, jedoch lag ich da wohl falsch.

Wie müsste denn ein Style dazu aussehen, damit dieser funktioniert?

3.430 Beiträge seit 2007
vor 13 Jahren

Hallo,

Wie müsste denn ein Style dazu aussehen, damit dieser funktioniert?

Hm, meine Idee einfach die Columns zu setzen wird wohl nicht funktionieren.
Denn die Columns sind nicht writeable deshalb kann man es nicht mit dem Style setzen.

Du könntest aber in deinem UserControl ein Property (Collection von Columns) definieren welche er dir setzen kann.
Diese fügst du dann als Spalten in deinem (internen) DataGrid hinzu.

Guckst du hier: Wie binde ich ein WPF DataGrid, eine variable Anzahl von Spalten?

Gruss
Michael

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren

Danke schonmal für den Link.
Ich habe das Ding nun entsprechend umgebaut, jedoch komme ich immernoch nicht richtig weiter. Vermutlich habe ich nicht genau genug geschrieben was ich möchte, deshalb nun etwas konkreter.

Ich benutze eine AutoCompleteBox von Silverlight um mit Hilfe eines Templates aus dieser ein Suchcontrol zu bauen. Prinzipiell möchte ich das Ding so generisch machen, dass der Benutzer einfach ein Template mit den benötigten Spalten generiert (im XAML) und eine Suchmethode von beliebiger Stelle (WCF Service) übergibt. Ersteres ist genau das Problem das ich jetzt habe. Ich habe das ControlTemplate der Autocompletebox überschrieben und dort im Popup nun das DataGrid reingesetzt. Dort möchte ich nun das Template mit den benötigten Spalten zuweisen, weiss aber leider nicht genau wie. Ich habe mit nun wie im Link von dir beschrieben eine DependencyProperty erstellt, die die Spalten entgegen nimmt. Diese werden auch an der richtigen Stelle geladen und erzeugt. Ich weiss nun allerdings nicht genau was gemacht werden muss, damit die Spalten an anderer Stelle gelesen werden können.

Ich könnte mir vorstellen, dass die AutoCompleteBox eine DP, ich nenn sie mal "PopupGridColumnTemplate" benötigt, die die Spalten für das DataGrid intern durchreicht. Diese würden dann mit dem bereits implementieren Teil aus dem Link das Control aufbauen.

Die Definition der Spalten soll dabei über ein (Data?)Template in den Ressourcen erfolgen.

Kurz und knapp: Ich definiere die Spalten und bestimmte die Darstellung meiner Daten. Über die ItemsSource der ACBox bekomme ich ja bereits meine Daten, kann also direkt die benötigten Properties binden.

1nf1n1ty Themenstarter:in
286 Beiträge seit 2007
vor 13 Jahren

Ich habe nun dort, wo ich zuvor hardcodiert das DataGrid das dargestellt werden soll, ein ContentControl eingefügt. Dem wollte ich nun als DataTemplate das ausgelagerte Datagrid mitgeben, damit er dieses zur Darstellung bekommt. Das wäre prinzipiell genau das, was ich möchte, nämlich das der Benutzer festlegen kann wie der Inhalt dargestellt werden soll. Leider Bleibt die Anzeige hierbei leider komplett leer.

Kann jemand nochmal darüber schauen?

Noch ein paar Hinweise:
QuickSearchControl ist abgeleitet von AutoCompleteBox.
PopupTemplate ist eine DependencyProperty, die ich in QuickSearchControl eingefügt habe und da soll dann das Template für die Darstellung hinterlegt werden.

Im Popuptemplate weise ich dgTest zu, da hier das Template hinterlegt ist.


<DataTemplate x:Key="dgTest" TargetType="sdk:DataGrid">
     <sdk:DataGrid>
         <sdk:DataGrid.Columns>
             <sdk:DataGridTextColumn Header="1" />
             <sdk:DataGridTextColumn Header="2" />
         </sdk:DataGrid.Columns>
     </sdk:DataGrid>
</DataTemplate>


<Style x:Key="QuickSearchTemplate" TargetType="uc:QuickSearchControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="uc:QuickSearchControl">
                <Grid Margin="{TemplateBinding Padding}">
                    <TextBox IsTabStop="True" x:Name="Text" Style="{TemplateBinding TextBoxStyle}" Margin="0"/>
                    <Popup x:Name="Popup">
                        <Border x:Name="PopupBorder" HorizontalAlignment="Stretch" Opacity="0.0" BorderThickness="0" CornerRadius="3" Background="#11000000">
                            <Border.RenderTransform>
                                <TranslateTransform X="2" Y="2"/>
                            </Border.RenderTransform>
                            <Border HorizontalAlignment="Stretch" BorderThickness="0" CornerRadius="3" Background="#11000000">
                                <Border.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform X="-1" Y="-1"/>
                                    </TransformGroup>
                                </Border.RenderTransform>
                                <Border HorizontalAlignment="Stretch" Opacity="1.0" Padding="1" BorderThickness="1" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3">
                                    <Border.RenderTransform>
                                        <TransformGroup>
                                            <ScaleTransform/>
                                            <SkewTransform/>
                                            <RotateTransform/>
                                            <TranslateTransform X="-2" Y="-2"/>
                                        </TransformGroup>
                                    </Border.RenderTransform>
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FFDDDDDD" Offset="0"/>
                                            <GradientStop Color="#AADDDDDD" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Border.Background>
                                                
                                    <!-- Hier war vorher das DataGrid, damit hats hardcodiert geklappt -->
                                    <ContentControl ContentTemplate="{TemplateBinding PopupTemplate}" />
                                                
                                </Border>
                            </Border>
                        </Border>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Vielen Dank.

[gelöst]
Ich habe nun nochmal mit Hilfe des Links von dir und ein paar kleinen Änderungen des Problem gelöst. Statt des ContentControls ist nun direkt das DataGrid an der Stelle. Über eine DP mache ich eine Eigenschaft für die Spalten verfügbar, damit ich diese im XAML definieren kann. Über eine Style-Eigenschaft an meinem Control konnte ich diese Definition dann intern zuweisen.

Vielen Dank nochmal für den Link. Der hat mir weitergeholfen und mich in die richtige Richtung gestubst. Nachdem ich nochmal ein paar Grundlagen nachgelesen habe ist mir klar geworden, dass ich da wohl etwas falsch verstanden habe.