2013-07-19 14 views
15

Jestem stoi problem z ustawieniem następujący układ: XAMLAuto Wzrost w połączeniu z maxheight

RowHeightAuto.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="GridMaxHeight.RowHeightAuto" 
    Title="RowHeightAuto" WindowState="Maximized"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition /> 
     <RowDefinition Height="Auto" MaxHeight="200" /> 
    </Grid.RowDefinitions> 

    <StackPanel Background="LightGray" Grid.Row="0"></StackPanel> 
    <DataGrid Name="DataGrid1" Grid.Row="1" /> 
</Grid> 

Kontrola DataGrid1 nie widać żadnych pasków przewijania z zdefiniowano wiele kolumn i wierszy. Wszystko działa, gdy zastępuję Wysokość = "Auto" z Wysokością = "*" niż paski przewijania w poziomie i pionie są wyświetlane tak, jak oczekiwano.

Działa również wtedy, gdy zadeklaruję MaxHeight bezpośrednio w DataGrid1, ale tak naprawdę nie chcę, chcę.

Czy jest to błąd, w którym sterowanie dziećmi ignoruje maksymalną wysokość ustawienia wysokości "Auto" lub czy proponuję coś nie tak? To samo zachowanie można odtworzyć za pomocą ListBox/ListView i tak dalej, również z kontrolkami innych firm, takimi jak ComponentOne, Telerik ...

Jeśli to błąd - czy znasz obejście lub masz dla mnie inne wskazówki?

Oto kod jak ustawić ItemsSource w DataGrid. RowHeightAuto.xaml.cs

public partial class RowHeightAuto : Window 
{ 
    private readonly DateTime _start; 

    public RowHeightAuto() 
    { 
     InitializeComponent(); 

     DataGrid1.ItemsSource = GetTestData(); 

     _start = DateTime.Now; 
     Dispatcher.BeginInvoke(new Action(() => MessageBox.Show((DateTime.Now - _start).TotalSeconds.ToString(CultureInfo.InvariantCulture))), DispatcherPriority.ContextIdle, null); 
    } 

    public static List<TestData> GetTestData() 
    { 
     const int maxCols = 501; 
     const int maxRows = 300; 

     var testDatas = new List<TestData>(maxRows); 
     for (int i = 0; i < maxRows; i++) 
      testDatas.Add(new TestData()); 

     for (int i = 0; i < maxCols; i++) 
     { 
      string propName = string.Format("Property{0}", AddLeadingZeros(i)); 

      for (int j = 0; j < maxRows; j++) 
       testDatas[j][propName] = propName; 
     } 

     return testDatas; 
    } 

    private static string AddLeadingZeros(int val) 
    { 
     return val.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0'); 
    } 
} 

public class TestData 
{ 
    public object this[string propertyName] 
    { 
     get 
     { 
      var myType = GetType(); 
      var myPropInfo = myType.GetProperty(propertyName); 
      return myPropInfo.GetValue(this); 
     } 
     set 
     { 
      var myType = GetType(); 
      var myPropInfo = myType.GetProperty(propertyName); 
      myPropInfo.SetValue(this, value, null); 

     } 
    } 

    public string Property000 { get; set; } 
    public string Property001 { get; set; } 
    public string Property002 { get; set; } 
    public string Property003 { get; set; } 
    ... 
    public string Property498 { get; set; } 
    public string Property499 { get; set; } 
    public string Property500 { get; set; } 

} 
+0

+1 za przyzwoicie sformatowane i udokumentowane pierwsze pytanie.Witaj w SO :) – Viv

+0

Proszę, nie możesz napisać 'string.Format (" Property {0: 000} ", i)' zamiast wywoływać metodę 'AddLeadingZeros'. – Clemens

+0

@ Viv: Dzięki. :) @ Clemens: Dzięki za wejście. Jestem noobem z formatami ciągów. :) –

Odpowiedz

7

To jest dokładnie tak jak mówisz to jest.

Powodem, dla którego nie widać Scrollbar „s jest bo chociaż Grid Klip jest DataGrid, to jedynie klipu, ActualHeight z DataGrid jest wysokość byłoby uzyskać, jeśli wolno, aby pokazać wszystkich jego dzieci. W ten sposób nie widzisz, że to pasek przewijania. ActualHeight jest tak, że można uzyskać całą przestrzeń, którą chce z Height="Auto" na Grid. Powodem, dla którego nie nazwałbym tego błędu osobiście, jest to, że możesz chcieć tego zachowania, jeśli chcesz grać z właściwością ClipToBounds z Grid dla pewnych animacji i jest to pożądane zachowanie. Myśląc o tym, tak naprawdę myślę Nazwałbym to błąd zbyt w kategoriach „nie jest pożądane funkcjonalności” niż „wyjścia incorrect”

Aby uzyskać zachowanie szukasz,

  • Zastosuj MaxHeight na DataGrid lub użyć siatki RowDefinition.Height="*" < - zarówno jak wspomniano (nie wiem, dlaczego mówisz, to nie jest to, co chcesz zrobić?)
  • albo można też użyć RelativeSourceBinding na DataGrid

coś -

<DataGrid Name="DataGrid1" 
      Grid.Row="1" 
      Height="{Binding RelativeSource={RelativeSource FindAncestor, 
          AncestorType={x:Type Grid}}, 
          Path=RowDefinitions[1].ActualHeight}"> 

Dla takich kwestiach Snoop jest twoim przyjacielem. Możesz łatwo sprawdzić to zachowanie i zdać sobie sprawę, dlaczego paski przewijania nie są wyświetlane, gdy sprawdzasz ActualHeight na swoim DataGrid używając Snoop i widzisz, że przydziela on trochę więcej wysokości kontroli podrzędnej.

+0

Naprawdę nie rozumiem, dlaczego tak się dzieje, w moim układzie mówię, stwierdzając, że chcę tylko MaxHeight 200. Czy możesz wyjaśnić nieco więcej, dlaczego ktoś chciałby mieć w pełni rozmiar elementu dziecięcego podczas określania MaxHeight? I może powód, dla którego nawet poziomy pasek postępu nie jest wyświetlany, co absolutnie nie ma dla mnie sensu. –

+0

@RandRandom Ale mówisz również "Height =" Auto ", co oznacza, że" zajmujesz całą przestrzeń, której potrzebujesz ". To tylko moja opinia. Można go zgłosić w MSDN jako błąd i zapytać, dlaczego określenie Auto nie wymusza, aby kontrola podrzędna respektowała 'MaxHeight' w' Grid.RowDefinition'. Według mnie, jeśli podasz "*" jako wysokość, dziecko może wziąć "dowolną dostępną przestrzeń od rodzica", która jest ograniczona przez MaxHeight, a więc wynik jest taki, jakiego oczekujesz. – Viv

+0

@RandRandom ..contd. Jednak po ustawieniu 'Height =" Auto "' występuje niedopasowanie, w którym rząd Grida na jednej ręce jest zmuszony do zrobienia tylko 200 w ActualHeight przez MaxHeight, podczas gdy dziecko może wziąć tyle, ile potrzebuje, za pomocą Auto for Height i zdarza się, że oba spełniają wymagania, dając dziecku miejsce, którego potrzebuje, kiedy rząd Grida jest zgodny z maks. 200, który mu podano. – Viv