Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's what I ended up doing to use this with the MVVM pattern:</p> <p>I have two sets of data for binding on my view model: one for the actual grid data and one for the column headers. Currently these are exposed as two properties:</p> <pre><code>// INotifyPropertyChanged support not shown for brevity public DataTable GridData { get; set; } public BindingList&lt;ImportColumnInfo&gt; ColumnData { get; set; } </code></pre> <p>The trick to working with two differing sets of data is in the grid. I have subclassed the DataGrid and given the grid an additional data source called ColumnSource, as a dependency property. This is what is bound to the ColumnData on my view model. I then set the header of each auto-generated column to the appropriately indexed data in the ColumnSource data source. The code is as follows:</p> <pre><code>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)); } </code></pre> <p>I can now perform normal data binding in the templated header of my columns, which will all bind against the data in the ColumnData property of my view model.</p> <p>UPDATE: I was asked to show the XAML for my grid. It's really basic, but here it is:</p> <pre><code>&lt;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" /&gt; </code></pre> <p>And here is the ImporterColumnHeaderStyle:</p> <pre><code>&lt;Style x:Key="ImporterDataGridColumnHeaderStyle" TargetType="{x:Type toolkit:DataGridColumnHeader}"&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type toolkit:DataGridColumnHeader}"&gt; &lt;Grid&gt; &lt;toolkit:DataGridHeaderBorder Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" IsClickable="{TemplateBinding CanUserSort}" IsHovered="False" IsPressed="False" SortDirection="{TemplateBinding SortDirection}"&gt; &lt;Grid&gt; &lt;CheckBox Height="16" Margin="6,6,16,0" Name="importCheckBox" IsChecked="{Binding Path=Import}" VerticalAlignment="Top"&gt;Import Column&lt;/CheckBox&gt; &lt;StackPanel IsEnabled="{Binding Path=Import}"&gt; &lt;ComboBox Height="24" Margin="6,29,6,0" Name="columnTypeComboBox" VerticalAlignment="Top" SelectedValue="{Binding ColumnType}" ItemsSource="{Binding Source={local:EnumList {x:Type Models:ImportColumnType}}}"&gt; &lt;/ComboBox&gt; &lt;TextBox Height="23" Margin="6,6,6,33" Name="customHeadingTextBox" VerticalAlignment="Bottom" Text="{Binding Path=CustomColumnName}" IsEnabled="{Binding ColumnType, Converter={StaticResource ColumnTypeToBooleanConverter}}" /&gt; &lt;/StackPanel&gt; &lt;TextBlock Height="20" Margin="6,0,6,7" Name="originalHeadingTextBlock" Text="{Binding Path=OriginalColumnName}" VerticalAlignment="Bottom" Foreground="Gray" /&gt; &lt;/Grid&gt; &lt;/toolkit:DataGridHeaderBorder&gt; &lt;Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left"&gt; &lt;Thumb.Style&gt; &lt;Style TargetType="{x:Type Thumb}"&gt; &lt;Setter Property="Width" Value="8"/&gt; &lt;Setter Property="Background" Value="Transparent"/&gt; &lt;Setter Property="Cursor" Value="SizeWE"/&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type Thumb}"&gt; &lt;Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; &lt;/Thumb.Style&gt; &lt;/Thumb&gt; &lt;Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right"&gt; &lt;Thumb.Style&gt; &lt;Style TargetType="{x:Type Thumb}"&gt; &lt;Setter Property="Width" Value="8"/&gt; &lt;Setter Property="Background" Value="Transparent"/&gt; &lt;Setter Property="Cursor" Value="SizeWE"/&gt; &lt;Setter Property="Template"&gt; &lt;Setter.Value&gt; &lt;ControlTemplate TargetType="{x:Type Thumb}"&gt; &lt;Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; &lt;/Thumb.Style&gt; &lt;/Thumb&gt; &lt;/Grid&gt; &lt;/ControlTemplate&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;/Style&gt; </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload