2011-08-09 28 views
11

Używam siatki jako ItemsPanel dla listy dynamicznie powiązanej z ItemsControl. Poniższy kod działa - z pozostałym problemem: nie mogę znaleźć sposobu na dynamiczne zainicjowanie ColumnDefinitions i RowDefinitions siatki. W konsekwencji wszystkie wartości są umieszczone jeden na drugim.Siatka WPF jako ItemsPanel dla listy dynamicznie powiązanej z ItemsControl

Należy pamiętać, że szukam odpowiedzi zgodnie ze wzorem MVVM. Dlatego podklasy i kodowanie są tylko obejściami, ale bez rozwiązań.

+0

Jaki układ jesteś po? Czy to możliwe, że UniformGrid może działać? – jeffora

+0

@jeffora: Potrzebuję co najmniej innej kolumny widht. Myślę, że UniformGrid nie jest opcją. –

+0

Nie myśląc o tym zbyt długo, czy uważasz, że [UniformGrid] (http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.uniformgrid.aspx) może być lepszym wyborem? – Will

Odpowiedz

19

Będziesz potrzebował jakiś sposób, aby poinformować Grid, ile ma wierszy/kolumn. Być może po załadowaniu każdej pozycji możesz sprawdzić wartość RowIndex i ColumnIndex i dodać wiersze/kolumny do siatki, jeśli to konieczne.

Jako inną alternatywę, być może można wystawiać RowCount i ColumnCount właściwości w Twojej ViewModel że zwróci max RowIndex i ColumnIndex, aw przypadku Loaded siatki dodają jednak wiele kolumn/wierszy, których potrzebujesz.

Uważam, że używanie kodu w MVVM jest całkowicie dopuszczalne, jeśli kod jest związany tylko z interfejsem użytkownika.

Innym pomysłem byłoby zorganizować swoje przedmioty w kodzie opóźnieniem w 2D siatki przed wpuszczeniem go do widoku, a następnie powiązać tego starcie do DataGrid z AutoGenerateColumns=True i nagłówki usuwane

Aktualizacja

Mój obecny rozwiązaniem tego problemu jest zastosowanie zestawu AttachedProperties dla Grid które pozwalają powiązać RowCount i ColumnCount własności do nieruchomości na ViewModel

Można znaleźć kod dla mojej wersji dołączonych właściwości na moim blogu here i mogą być używane tak:

<ItemsPanelTemplate> 
    <Grid local:GridHelpers.RowCount="{Binding RowCount}" 
      local:GridHelpers.ColumnCount="{Binding ColumnCount}" /> 
</ItemsPanelTemplate> 
+0

Dziękuję za odpowiedź. Rozwiązano to zgodnie z drugą sugestią (wydarzenie Grid's Loaded). Myślę, że masz rację z opinią na temat kodu MVVM. Początkowo szukałem czegoś w rodzaju "wiązania danych z definicjami siatki", ale WPF wydaje się nie być teraz przyjazny dla MVVM. –

+0

Mam nadzieję zrobić to samo, z wyjątkiem tego, że chciałbym TextBlock w rzędzie 0 i TextBlock w rzędzie 1, jakikolwiek pomysł, jak to zrobić? –

+1

@didibus Nie można tego łatwo zrobić za pomocą 'ItemsControl' podczas próby dodania dwóch osobnych elementów do' ItemsPanel' (w tym przypadku 'Grid') z każdym rekordem, a każdy rekord jest zawijany w pojedynczy plik'. ContentPresenter'. Powinieneś albo uczynić twój 'ItemTemplate' własnym' Grid'em z 2 komórkami (możesz użyć 'SharedSizeScope', aby zrobić je wszystkie w tym samym rozmiarze, jeśli to konieczne), albo powinieneś użyć innej kontroli niż' ItemsControl' do wyświetlenia twoje przedmioty, takie jak 'DataGrid'. Jeśli utkniesz, opublikuj pytanie na SO z odpowiednimi fragmentami kodu, a ja z przyjemnością go obejrzę :) – Rachel

2

Twoja siatka ma zero wierszy i kolumn, więc wszystko będzie wyświetlane jeden na drugim. Zrób coś jak poniżej i to zadziała.

<ItemsControl ItemsSource="{Binding Cells}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="Auto" /> 
       </Grid.RowDefinitions> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="Auto" /> 
       </Grid.ColumnDefinitions> 
      </Grid> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle> 
     <Style> 
      <Setter Property="Grid.Row" Value="{Binding RowIndex}" /> 
      <Setter Property="Grid.Column" Value="{Binding ColumnIndex}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Value}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+1

Jestem tego świadomy. Ale moja siatka ma dynamicznie rosnącą liczbę kolumn i rzędów. Nie mogę użyć statycznego schematu, takiego jak powyższy. –

+0

@Wallstreet Programmer: było dokładnie tym, czego szukałem. wielkie dzięki!! –

Powiązane problemy