2009-05-11 10 views
2

Ich habe ein Projekt, das eine DataGrid mit einer benutzerdefinierten Vorlage verwendet, so dass ich eine spezielle Zeile an den unteren Rand der Datenzeilen hinzufügen kann. Ich möchte, dass diese spezielle Zeile unter der letzten Zeile gepinnt wird, aber nicht als Teil der ScrollViewer, so dass sie unter der letzten Zeile angeheftet bleibt, bis die Unterseite der speziellen Zeile die Unterseite des Datenrasters erreicht, dann möchte ich die Reihen Sie die Region auf die Größe dazwischen und scrollen Sie entsprechend, wobei die spezielle Reihe immer sichtbar ist.Wie stecke ich ein Steuerelement unter einem anderen in Silverlight?

Bisher habe ich meine spezielle Zeile als Teil der ScrollViewer zusammen mit der RowsPresenter. Sowohl der Presenter als auch die spezielle Zeile befinden sich in den Zeilen Grid innerhalb der ScrollViewer, die ScrollViewer in einer sternförmigen Rasterzeile, so dass die Bildlaufleiste angezeigt wird, wenn kein Platz mehr vorhanden ist. Wie bekomme ich das heraus, wo die Zeilen und die spezielle Zeile zusammen rollen, wo ich sein will, wo die Zeilen rollen, aber die spezielle Zeile unten angeheftet und immer sichtbar ist?

Obwohl mein Beispiel eine DataGrid verwendet, bin ich mir sicher, dass dies vereinfacht werden kann, um nur ein scrollbares Element von unterschiedlicher Höhe und ein Steuerelement darunter zu pinnen. Bis jetzt stelle ich mir vor, ich brauche eine Canvas anstatt eine Grid zu hosten meine ScrollViewer und Companion spezielle Zeile, mit etwas Logik Höhen und Positionen zu justieren, wenn die ScrollViewer wächst (wenn ich das erkennen kann), aber ich habe dies noch nicht versucht . Gibt es einen besseren Weg oder ist der Canvas Ansatz der beste?

Antwort

1

Ich konnte dies lösen, indem Sie eine Grid mit zwei automatisch großen Zeilen verwenden; eine Reihe für die DataGrid und eine Reihe für meine gepinnte Reihe. Ich überwache dann die Größe der Grid und schaue bei der Größenanpassung, ob die ActualHeight von Grid größer ist als die Bildschirmgrundfläche, die belegt werden soll. Wenn dies der Fall ist, ändere ich die Zeile DataGrid in Sterngröße, was dazu führt, dass die gepinnte Zeile am unteren Rand des übergeordneten Steuerelements angezeigt wird und die DataGrid eine Bildlaufleiste für ihre Zeilen anzeigt. Ich ändere die Zeile zurück in die automatische Größenanpassung, wenn mehr Platz zur Verfügung steht.

Dies würde natürlich für jedes Szenario funktionieren, in dem eine Zeile immer auf dem Bildschirm sein muss, aber auch an der Unterseite eines anderen angeheftet werden muss.

Der Pinning-Code sieht etwa so aus:

RowDefinition row = this.mainGrid.RowDefinitions[0]; 
if (row.Height.GridUnitType == GridUnitType.Auto) 
{ 
    if (this.mainGrid.ActualHeight > this.ActualHeight) 
    { 
     row.Height = new GridLength(1, GridUnitType.Star); 
    } 
} 
else 
{ 
    if (this.dataGrid.DesiredSize.Height < row.ActualHeight) 
    { 
     row.Height = GridLength.Auto; 
    } 
} 
0

Zuerst ein Gitter für die Hauptsteuerung erstellen und die gepinnten Kontrolle:

<Grid Grid.Row="0" VerticalAlignment="Top"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" />    
     <RowDefinition Height="Auto" />    
    </Grid.RowDefinitions> 

    <!-- The main control, that is about to stretch. --> 
    <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding YOUR_COLLECTION}" /> 

    <!-- The pinned control. --> 
    <TextBlock Grid.Row="1" Text="Hello World" /> 
</Grid> 

Der Trick ist, Vertical = "Top" - wenn Ist das Hauptsteuerelement kleiner als die verfügbare Höhe, wird es an den Anfang des verfügbaren Speicherplatzes verschoben und das festgelegte Steuerelement wird darunter angezeigt.

Dann wird dieses Gitter in einen Behälter gegeben, der vertikal mit Stern Höhe in einer Reihe von anderen Grid beispiels Dehnt

<Grid x:Name="LayoutRoot"> 
    <Grid.RowDefinitions> 
     <!-- RowDefition for the Grid with the main control and the pinned control. --> 
     <!-- If you want to have some other controls, --> 
     <!-- add other RowDefinitions and put these controls there. --> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

    <!-- The internal Grid for the main control and the pinned control. --> 
    <Grid Grid.Row="0" VerticalAlignment="Top"> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" />    
      <RowDefinition Height="Auto" />    
     </Grid.RowDefinitions> 

     <sdk:DataGrid Grid.Row="0" ItemsSource="{Binding YOUR_COLLECTION}" /> 

     <TextBlock Grid.Row="1" Text="Hello World" /> 
    </Grid> 
</Grid> 

Anstelle des Wurzel Tabelle Sie andere Behälter aufweisen kann, die sich vertikal erstreckt, Wichtig ist, dass es versucht, den gesamten verfügbaren Platz dafür zu füllen.

Verwandte Themen