Hier ist, was ich das mit dem Muster MVVM tat am Ende zu verwenden:
ich habe zwei Sätze von Daten für auf meiner Ansicht nach Modell Bindung: ein für die tatsächlichen Netzdaten und eine für die Spaltenüberschriften .Gegenwärtig sind diese als zwei Eigenschaften exponiert:
// INotifyPropertyChanged support not shown for brevity
public DataTable GridData { get; set; }
public BindingList<ImportColumnInfo> ColumnData { get; set; }
Der Trick zum Arbeiten mit zwei unterschiedlichen Datensätzen ist im Raster. Ich habe das DataGrid unterklassifiziert und dem Gitter eine zusätzliche Datenquelle namens ColumnSource als Abhängigkeitseigenschaft gegeben. Dies ist, was an die ColumnData in meinem Ansichtsmodell gebunden ist. Ich setze dann den Header jeder automatisch generierten Spalte auf die entsprechend indizierten Daten in der ColumnSource-Datenquelle. Der Code lautet wie folgt:
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));
}
ich jetzt normale Datenbindung in den Templat-Header meiner Spalten durchführen können, das wird alle binden gegen die Daten in der ColumnData Eigenschaft meiner Ansicht Modell.
UPDATE: Ich wurde gebeten, den XAML für mein Raster zu zeigen. Es ist wirklich einfach, aber hier ist es:
<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" />
Und hier ist der 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>
Wäre interessant, wenn Sie die ganze Lösung sehen. Was ist zum Beispiel "ImporterDataGridColumn"? –
Sie können ImporterDataGridColumn ignorieren und nur DataGridTextColumn verwenden. Es ist nur eine Standardspalte, die ich unterklassifiziert habe und dachte, dass ich zusätzliche Funktionalität benötigen würde, aber nicht. Der gesamte Netzcode ist oben. Das Ansichtsmodell stellt die oben aufgeführten Eigenschaften GridData und ColumnData zur Verfügung, wobei Daten von wo immer Sie möchten aufgefüllt werden. Das XAML hakt dann die beiden nach oben: –
Könnten Sie (hübsch bitte) hinzufügen Ansicht xaml dafür? –