2012-12-11 19 views
6

Mam kolekcję, którą chcę powiązać z siatką WPF.siatka wpf z dynamicznymi kolumnami

Problem, który napotykam, polega na tym, że liczba kolumn jest dynamiczna i zależy od kolekcji. Oto prosty przykład:

public interface IRows 
{ 
    string Message{get;} 
    IColumns[] Columns{get;} 
} 

public interface IColumns 
{ 
    string Header {get;} 
    AcknowledgementState AcknowledgementState{get;} 
} 

public interface IViewModel 
{ 
    ObservableCollection<IRows> Rows {get;} 
} 

Chcę, aby mój widok był powiązany z kolekcją Wiersze zawierającą kolekcję kolumn.

Kolekcja Moje kolumny zawiera wyliczenie, które powinno być reprezentowane przez obraz (1 z 3 możliwości). Zawiera także właściwość Message, która powinna być wyświetlana tylko w jednej kolumnie (statyczna i jest to tylko część informacji tekstowych). Zawiera również ciąg nagłówka, który powinien być wyświetlany jako nagłówek tej kolumny.

The link to what I want to show

Należy zauważyć, że liczba kolumn jest zmienna (w tej chwili nagłówki są ustawione, aby potwierdzić, ale to się zmieni do reprezentowania danych dynamicznych).

Aktualizacja: To jest po wdrożeniu sugestii Rachel

<ItemsControl 
ItemsSource="{Binding Items, Converter={StaticResource PresentationConverter}}"> 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Grid ShowGridLines="true" 
     local:GridHelpers.RowCount="{Binding RowCount}" 
     local:GridHelpers.ColumnCount="{Binding ColumnCount}" /> 
    </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> 
     <ContentControl Content="{Binding}"> 
     <ContentControl.Resources> 
      <DataTemplate DataType="{x:Type UI:MessageEntity}"> 
      <TextBox Text="{Binding Message}"></TextBox> 
      </DataTemplate> 
      <DataTemplate DataType="{x:Type UI:StateEntity}"> 
      <TextBox Text="{Binding State}"></TextBox> 
      </DataTemplate> 
     </ContentControl.Resources> 
     </ContentControl> 
    </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

To prawie daje mi to, co chcę teraz. Utknąłem tylko z tym, co powinienem zrobić dla nagłówków. Wszelkie sugestie są mile widziane.

+0

do odbioru, daje maksimum informacji. Obejmuje link ... – Harry

+0

Uproszczone i dodane łącze. – zman

+0

Link do dynamicznego dodawania wierszy i kolorów - http://stackoverflow.com/questions/13344788/how-to-create-listview-to-a-grid-programmatically/ – Sai

Odpowiedz

5

Można używać zagnieżdżonych ItemsControls tego

Oto prosty przykład:

<!-- Bind Rows using the default StackPanel for the ItemsPanel --> 
<ItemsControl ItemsSource="{Binding Rows}"> 
    <!-- Set the Template for each row to a TextBlock and another ItemsControl --> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <!-- Need to set Width of name TextBlock so items line up correctly --> 
       <TextBlock Width="200" Text="{Binding Name}" /> 

       <ItemsControl ItemsSource="{Binding Columns}"> 
        <!-- Use a horizontal StackPanel to display columns --> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel Orientation="Horizontal" /> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

To jest prawie to, czego chcę. Próbowałem wdrażanie rozwiązania z wykorzystaniem tego pomysłu, ale znalazłem problemy, gdy dodałem wiersz nagłówka, który zrobiłem niezależnie od ItemsControl (tylko panel stosu powyżej). Trudno jest ustawić szerokość kolumn tak, aby były zsynchronizowane. – zman

+1

@ManuelZanin Można użyć siatki z dołączoną właściwością [SharedSizeScope] (http://msdn.microsoft.com/en-us/library/system.windows.controls.grid.issharedsizescope.aspx), jednak wymaga to wcześniej zdefiniować definicje kolumn. Jeśli liczba kolumn może się zmienić, mam pewne załączone właściwości dla Grid [na moim blogu] (http://rachel53461.wordpress.com/2011/09/17/wpf-grids-rowcolumn-count-properties/), które pozwala powiązać liczbę kolumn zamiast ręcznie określać ColumnDefinitions. – Rachel

+0

Ok Mam prawie gotowe do pracy dzięki twoim sugestiom. Zaktualizowałem moje pytanie. Pozostaje tylko kwestia, jak sobie poradzić z nagłówkami. Jeśli nie mogę uzyskać działającego przy użyciu ItemsControl, może będę musiał użyć ListView (chociaż nie jestem bardzo obeznany z tym sterowaniem). – zman

2

Korzystanie z podejścia sieciowego może sprawić, że sprawy będą bardziej skomplikowane, niż powinny. Czy próbowałeś zmienić szablon widoku listy lub użyć zamiast tego DataGrid do tego celu?

Dla przykładu, spojrzeć na ten projekt: http://www.codeproject.com/Articles/25058/ListView-Layout-Manager

Albo ten: http://www.codeproject.com/Articles/16009/A-Much-Easier-to-Use-ListView

Jeśli pójdziesz z siatki, wierzę, będziesz musiał włożyć dużo kodu do tyłu zarządzaj ilością kolumn i wierszy, ich rozmiarem, zawartością komórki ... Podczas gdy ListView/DataGrid pozwala to zrobić dynamicznie za pomocą szablonów.

+0

Te linki nie dotyczą kolekcji kolumn, którą widziałem. – Paparazzi

+0

@Blam I nie mają do czynienia z siatką! I to jest właśnie mój punkt widzenia: DataTemplate wewnątrz ListView może być lepszym rozwiązaniem dla scenariusza OP. Kiedy zacząłem WPF, zacząłem kiedyś kodować klasę, która generowałaby Grid z nieznaną ilością kolumn + nagłówków, i ostatecznie dowiedziałem się o ListView i jak to upraszcza ten problem - zwłaszcza, że ​​OP chce, żeby to był czysty Rozwiązanie XAML. – Joe

+0

Masz rację, może sprawię, że życie będzie dla mnie zbyt trudne. Myślałem o użyciu ListView/GridView, ale nie znalazłem żadnych przykładów ich używania do osiągnięcia tego, co chcę (jestem dość zardzewiały na WPF, który nie pomaga). Zamieszczone przez Ciebie przykłady są przydatne, ale moim zdaniem to przesada. – zman

0

Istnieje również możliwość użycia dynamicznego obiektu do utworzenia kolumn. Jest to trochę pracochłonne, ale wyniki są bardzo skuteczne, a rozwiązanie w ogóle jest dość elastyczne.

To pokaże podstawy do dynamicznego obiektu Binding DynamicObject to a DataGrid with automatic column generation?

miałem pewne problemy z używaniem go z obiektów zagnieżdżonych, kolumny, które mają obiekty, a następnie starają się powiązać zawartość komórki do obiektu.

Oto pytanie podniosłem z przykładem, jak to zrobić pomocy

Problems binding to a the content of a WPF DataGridCell in XAML

Powiązane problemy