Domanda

Sto cercando di capire come associare intestazione di colonna di un DataGrid WPF e dei dati principali a un'origine dati utilizzando un modello MVVM. Il risultato che sto cercando sarebbe simile a questa:

alt text
(fonte: vallelunga.com )

ho stile con successo le intestazioni qui, ma io sono sicuro come associare i valori nelle intestazioni. In particolare, la proprietà IsChecked del check-box, l'indice selezionato della casella combinata e il valore della casella di testo.

Sono stato in precedenza usando un semplice DataTable per popolare i dati della griglia principali, ma ho intenzione di bisogno di qualcosa di più complesso per contenere sia i dati di rete e i valori per ogni colonna. O forse li posso archiviare come entità separate del tutto.

Quindi, qualcuno ha qualche idea di come avrei potuto tirare fuori questo legame? Una limitazione è che le colonne devono essere generati automaticamente dal momento che non ho idea di quello che sarà fino al runtime. L'applicazione semplicemente carica i dati formano un foglio Excel e ci possono essere un qualsiasi numero di colonne presenti.

Grazie, Brian

È stato utile?

Soluzione

Ecco quello che ho finito per fare per utilizzare questo con il modello MVVM:

Ho due insiemi di dati per la rilegatura sul mio vista del modello: una per i dati della griglia effettivi e uno per le intestazioni delle colonne. Attualmente questi sono esposti come due proprietà:

// INotifyPropertyChanged support not shown for brevity
public DataTable GridData { get; set; } 
public BindingList<ImportColumnInfo> ColumnData { get; set; }

Il trucco per lavorare con due insiemi differenti di dati è nella griglia. Ho sottoclasse DataGrid e data la griglia un'origine dati aggiuntivo chiamato ColumnSource, come una proprietà di dipendenza. Questo è ciò che è legato alla ColumnData sul mio modello di vista. Ho quindi impostare l'intestazione di ogni colonna generata automaticamente ai dati opportunamente indicizzati nell'origine dati ColumnSource. Il codice è il seguente:

public class ImporterDataGrid : DataGrid
{
    protected override void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
    {
        base.OnAutoGeneratingColumn(e);

        int columnIndex = this.Columns.Count;
        var column = new ImporterDataGridColumn();
        column.Header = ColumnSource[columnIndex];
        column.Binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };
        e.Column = column;
    }

    public IList ColumnSource
    {
        get { return (IList)GetValue(ColumnSourceProperty); }
        set { SetValue(ColumnSourceProperty, value); }
    }

    public static readonly DependencyProperty ColumnSourceProperty = DependencyProperty.Register("ColumnSource", typeof(IList), typeof(ImporterDataGrid), new FrameworkPropertyMetadata(null));

}

Ora posso eseguire dati normali associazione nell'intestazione su modelli dei miei articoli, che saranno tutti legano contro i dati nella proprietà ColumnData del mio modello di vista.

UPDATE: Mi è stato chiesto di mostrare il codice XAML per la mia rete. E 'davvero semplice, ma qui è:

<Controls:ImporterDataGrid 
    AutoGenerateColumns="True" x:Name="previewDataGrid"
    VerticalScrollBarVisibility="Visible"
    HorizontalScrollBarVisibility="Visible"
    IsReadOnly="True"
    SelectionMode="Extended"
    HeadersVisibility="Column"
    ItemsSource="{Binding PreviewData}"
    ColumnSource="{Binding PreviewColumnData}"
    Style="{StaticResource ImporterDataGridStyle}"
    Background="White" CanUserReorderColumns="False" CanUserResizeRows="False"
    CanUserSortColumns="False" AlternatingRowBackground="#FFFAFAFA" AllowDrop="True" />

Ed ecco l'ImporterColumnHeaderStyle:

<Style x:Key="ImporterDataGridColumnHeaderStyle" TargetType="{x:Type toolkit:DataGridColumnHeader}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type toolkit:DataGridColumnHeader}">
                <Grid>
                    <toolkit:DataGridHeaderBorder Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" IsClickable="{TemplateBinding CanUserSort}" IsHovered="False" IsPressed="False" SortDirection="{TemplateBinding SortDirection}">
                        <Grid>
                            <CheckBox Height="16" Margin="6,6,16,0" Name="importCheckBox" IsChecked="{Binding Path=Import}" VerticalAlignment="Top">Import Column</CheckBox>
                            <StackPanel IsEnabled="{Binding Path=Import}">
                                <ComboBox Height="24" Margin="6,29,6,0" Name="columnTypeComboBox" VerticalAlignment="Top" SelectedValue="{Binding ColumnType}" ItemsSource="{Binding Source={local:EnumList {x:Type Models:ImportColumnType}}}">
                                </ComboBox>
                                <TextBox Height="23"  Margin="6,6,6,33" Name="customHeadingTextBox" VerticalAlignment="Bottom" Text="{Binding Path=CustomColumnName}" IsEnabled="{Binding ColumnType, Converter={StaticResource ColumnTypeToBooleanConverter}}" />
                            </StackPanel>
                            <TextBlock Height="20" Margin="6,0,6,7" Name="originalHeadingTextBlock" Text="{Binding Path=OriginalColumnName}" VerticalAlignment="Bottom" Foreground="Gray" />
                        </Grid>
                    </toolkit:DataGridHeaderBorder>

                    <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left">
                        <Thumb.Style>
                            <Style TargetType="{x:Type Thumb}">
                                <Setter Property="Width" Value="8"/>
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="Cursor" Value="SizeWE"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Thumb}">
                                            <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Thumb.Style>
                    </Thumb>
                    <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right">
                        <Thumb.Style>
                            <Style TargetType="{x:Type Thumb}">
                                <Setter Property="Width" Value="8"/>
                                <Setter Property="Background" Value="Transparent"/>
                                <Setter Property="Cursor" Value="SizeWE"/>
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Thumb}">
                                            <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </Thumb.Style>
                    </Thumb>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Altri suggerimenti

Io sono sicuramente un WPF / MVVM / associazione dati niubbo, ma hanno lavorato duramente su questa roba ultimamente. Io non so quello che avete cablato fino ad oggi, ma prima ti consigliamo di impostare il DataContext per la visualizzazione. Dal momento che si sta utilizzando MVVM, suppongo che voi avete un ViewModel, in modo che dovrebbe essere il DataContext per la visualizzazione.

vale a dire. se avete il vostro CREATE VIEW / possedere il ViewModel, potrebbe essere simile a questa:

MyViewModel vm = new MyViewModel();
this.DataContext = vm;

Si può facilmente DataBind tua CheckBox, ComboBox e TextBox per immobili a vostro ViewModel. Ho trovato il modo più semplice è quello di rendere il vostro ereditare ViewModel da una classe base ViewModel, come il uno che Josh Smith scritto. Questo vi darà un metodo da chiamare internamente quando si desidera che il ViewModel di notificare l'interfaccia grafica di qualsiasi modifica dei valori.

Supponendo di avere immobili come ImportColumn, Cognome, e LastNameText (tutte le proprietà C #, non campi che la chiamata OnPropertyChanged di conseguenza), allora il vostro XAML sarebbe simile a questa:

<CheckBox IsChecked="{Binding ImportColumn}" />
<ComboBox SelectedItem="{Binding LastName}" />
<TextBox Text="{Binding LastName Text, Mode=TwoWay}" />

Spero che questo ti aiuta. In caso contrario, si prega di commento e cercherò di fare nel miglior modo possibile per provare altre cose.

Facciamo qualcosa di simile nella nostra applicazione.

Quello che ho fatto è derivato il mio tipo di colonna (DataGridSearchableBooleanColumn), poi i sostituire il modello DataGridColumnHeader, ho messo due presentatori di contenuti in là. il primo si legano i per il contenuto (la stessa del modello predefinito) il secondo mi legano alla colonna. Io uso un modello di dati per la colonna (ho un paio di loro per i diversi tipi di ricerca (testo, combo, booleani). Poi aggiungo le proprietà in più per la colonna in modo che io possa legarsi a loro. Vedere se questo codice ha un senso.

   <!--Style for the datagrid column headers, contains a text box for searching-->
   <Style
      x:Key="columnHeaderStyle"
      TargetType="dg:DataGridColumnHeader">
      <Setter
         Property="Foreground"
         Value="#FF000000" />
      <Setter
         Property="HorizontalContentAlignment"
         Value="Left" />
      <Setter
         Property="VerticalContentAlignment"
         Value="Center" />
      <Setter
         Property="IsTabStop"
         Value="False" />
      <Setter
         Property="Padding"
         Value="1,2,1,2" />
      <Setter
         Property="Template">
         <Setter.Value>
            <ControlTemplate
               TargetType="dg:DataGridColumnHeader">
               <Grid
                  x:Name="Root">
                  <dg:DataGridHeaderBorder
                     Background="{TemplateBinding Background}"
                     BorderBrush="{TemplateBinding BorderBrush}"
                     BorderThickness="{TemplateBinding BorderThickness}"
                     Padding="{TemplateBinding Padding}"
                     IsClickable="{TemplateBinding CanUserSort}"
                     IsHovered="{TemplateBinding IsMouseOver}"
                     IsPressed="{TemplateBinding IsPressed}"
                     SeparatorBrush="{TemplateBinding SeparatorBrush}"
                     SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
                     SortDirection="{TemplateBinding SortDirection}">

                     <Grid
                        HorizontalAlignment="Stretch"
                        Margin="{TemplateBinding Padding}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                        <Grid.Resources>
                           <DataTemplate
                              DataType="{x:Type local:DataGridSearchableBooleanColumn}">
                              <CheckBox
                                 Margin="0,5,0,0"
                                 IsThreeState="True"
                                 IsChecked="{Binding Path=IsChecked}" />
                           </DataTemplate>
                        </Grid.Resources>
                        <Grid.ColumnDefinitions>
                           <ColumnDefinition />
                           <ColumnDefinition
                              Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                           <RowDefinition
                              Height="19" />
                           <RowDefinition
                              Height="Auto" />
                        </Grid.RowDefinitions>

                        <ContentPresenter
                           Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Path=Content}" />

                        <Path
                           x:Name="SortIcon"
                           Fill="#FF444444"
                           Stretch="Uniform"
                           HorizontalAlignment="Left"
                           Margin="4,0,0,0"
                           VerticalAlignment="Center"
                           Width="8"
                           Opacity="0"
                           RenderTransformOrigin=".5,.5"
                           Grid.Column="1"
                           Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z ">
                           <Path.RenderTransform>
                              <ScaleTransform
                                 ScaleX=".9"
                                 ScaleY=".9" />
                           </Path.RenderTransform>
                        </Path>
                        <ContentPresenter
                           x:Name="columnHeaderContentPresenter"
                           Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Column}"
                           Grid.Row="1"
                           Grid.ColumnSpan="2"
                           Margin="0,0,0,0" />
                     </Grid>
                  </dg:DataGridHeaderBorder>

                  <Thumb
                     x:Name="PART_LeftHeaderGripper"
                     HorizontalAlignment="Left">
                     <Thumb.Style>
                        <Style
                           TargetType="{x:Type Thumb}">
                           <Setter
                              Property="Width"
                              Value="8" />
                           <Setter
                              Property="Background"
                              Value="Transparent" />
                           <Setter
                              Property="Cursor"
                              Value="SizeWE" />
                           <Setter
                              Property="Template">
                              <Setter.Value>
                                 <ControlTemplate
                                    TargetType="{x:Type Thumb}">
                                    <Border
                                       Background="{TemplateBinding Background}"
                                       Padding="{TemplateBinding Padding}" />
                                 </ControlTemplate>
                              </Setter.Value>
                           </Setter>
                        </Style>
                     </Thumb.Style>
                  </Thumb>
                  <Thumb
                     x:Name="PART_RightHeaderGripper"
                     HorizontalAlignment="Right">
                     <Thumb.Style>
                        <Style
                           TargetType="{x:Type Thumb}">
                           <Setter
                              Property="Width"
                              Value="8" />
                           <Setter
                              Property="Background"
                              Value="Transparent" />
                           <Setter
                              Property="Cursor"
                              Value="SizeWE" />
                           <Setter
                              Property="Template">
                              <Setter.Value>
                                 <ControlTemplate
                                    TargetType="{x:Type Thumb}">
                                    <Border
                                       Background="{TemplateBinding Background}"
                                       Padding="{TemplateBinding Padding}" />
                                 </ControlTemplate>
                              </Setter.Value>
                           </Setter>
                        </Style>
                     </Thumb.Style>
                  </Thumb>
               </Grid>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
   </Style>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top