Вот решение, которое использует программный код для динамического добавления правильных столбцов в DataGrid
. Вам понадобится только представление PageViewBase
, поэтому вы, вероятно, захотите переименовать его, так как оно не будет «основой» для чего-либо.
В UserControl.Resources
добавьте все возможные столбцы DataGrid
, которые вы можете иметь для всех ваших различных моделей. Например,
<UserControl.Resources>
<!-- Converters -->
<localHelpers:DateTimeConverter x:Key="dateTimeConverter" />
<localHelpers:StatusColorConverter x:Key="statusColorConverter" />
<!-- DataGrid Columns -->
<DataGridTextColumn x:Key="IdColumn" Header="Id" Binding="{Binding Id}" />
<DataGridTextColumn x:Key="TypeColumn" Header="Type" Binding="{Binding Type}" />
<DataGridTextColumn x:Key="LabelColumn" Header="Number" Binding="{Binding Label}" />
<DataGridTextColumn x:Key="LastModifiedColumn" Header="LastModifiedAt" Binding="{Binding LastModifiedAt, Converter={StaticResource dateTimeConverter}}" />
<!-- More column definitions go here for all model types -->
</UserControl.Resources>
Обязательно ставьте столбцы после преобразователей, чтобы их можно было использовать при привязке данных. Теперь измените DataGrid
, чтобы он запускал код при загрузке. Кроме того, удалите ContentPresenter
:
<DataGrid
ItemsSource="{Binding ItemsList}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
Grid.Row="1"
AutoGenerateColumns="False"
SelectionMode="Single"
Loaded="DataGrid_OnLoaded"
>
<DataGrid.ContextMenu> </DataGrid.ContextMenu>
<DataGrid.InputBindings> </DataGrid.InputBindings>
<DataGrid.Resources> </DataGrid.Resources>
<DataGrid.RowStyle> </DataGrid.RowStyle>
<!-- Columns are loaded in code-behind -->
</DataGrid>
В выделенном фрагменте кода добавьте правильные столбцы DataGrid
в зависимости от типа модели представления, привязанной к конкретному представлению (полученному через DataContext
представления):
private void DataGrid_OnLoaded(object sender, RoutedEventArgs e)
{
if (sender is DataGrid dataGrid)
{
if (DataContext is HardwareViewModel)
{
dataGrid.Columns.Add(Resources["IdColumn"] as DataGridColumn);
dataGrid.Columns.Add(Resources["TypeColumn"] as DataGridColumn);
// More columns added here
}
else if (DataContext is AnotherHardwareViewModel)
{
dataGrid.Columns.Add(Resources["IdColumn"] as DataGridColumn);
dataGrid.Columns.Add(Resources["LabelColumn"] as DataGridColumn);
dataGrid.Columns.Add(Resources["LastModifiedColumn"] as DataGridColumn);
// More columns added here
}
}
}
Наконец, тот, кто создает PageViewBase
, должен связать его с желаемой моделью представления для определенного типа, который вы хотите. Например,
<StackPanel>
<local:PageViewBase DataContext="{Binding HardwareViewModel}" />
<local:PageViewBase DataContext="{Binding AnotherHardwareViewModel}" />
</StackPanel>
Я протестировал это решение для простого случая и правильно получил разные наборы столбцов в двух DataGrid
с. Однако я не пробовал это в более сложном случае, поэтому заранее прошу прощения, если это не решит вашу конкретную проблему.