我有一个PageViewModelBase
,孩子需要实现3种方法,一切都按预期进行,因此,我想创建PageViewBase
并让其孩子实现两个简单的非泛型事物(即:数据上下文绑定和数据网格列)。
我遇到过this post,并试图相应地创建基本xaml(如下代码),但是尽管方法不同,但我无法创建子视图。我尝试过<baseView:PageViewBase>
是xaml中的唯一元素,并将其嵌入到另一个UserControl中,但是两种方法都失败了。
基本视图(省略了很多噪声代码,添加了子视图必须实现以实现可视化的示例部分):
<UserControl x:Class="WPFapp.Views.Base.PageViewBase">
<UserControl.Resources>
<!--<DataTemplate DataType="{x:Type localVM:HardwareViewModel}">
<local:HardwareView/>
</DataTemplate>-->
<localHelpers:DateTimeConverter x:Key="dateTimeConverter" />
<localHelpers:StatusColorConverter x:Key="statusColorConverter" />
</UserControl.Resources>
<UserControl.InputBindings> </UserControl.InputBindings>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="1*" MinHeight="25" />
<RowDefinition Height="15*" />
</Grid.RowDefinitions>
<ToolBarPanel Grid.Row="0" Orientation="Horizontal">
</ToolBarPanel>
<DataGrid ItemsSource="{Binding ItemsList}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" Grid.Row="1" AutoGenerateColumns="False" SelectionMode="Single">
<DataGrid.ContextMenu> </DataGrid.ContextMenu>
<DataGrid.InputBindings> </DataGrid.InputBindings>
<DataGrid.Resources> </DataGrid.Resources>
<DataGrid.RowStyle> </DataGrid.RowStyle>
<ContentPresenter ContentSource="Content"/>
<!--<DataGrid.Columns>
<DataGridTextColumn Header="LastModifiedBy" Binding="{Binding LastModifiedBy}" />
</DataGrid.Columns>-->
</DataGrid>
</Grid>
</UserControl>
子视图:
<UserControl x:Class="WPFapp.Views.HardwareView">
<UserControl.Resources>
<DataTemplate DataType="{x:Type localVM:HardwareViewModel}">
<local:HardwareView/>
</DataTemplate>
</UserControl.Resources>
<baseView:PageViewBase>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Id}" />
<DataGridTextColumn Header="Type" Binding="{Binding Type}" />
<DataGridTextColumn Header="Label" Binding="{Binding Label}" />
<DataGridTextColumn Header="Description" Binding="{Binding Description}" />
<DataGridTextColumn Header="LastModifiedBy" Binding="{Binding LastModifiedBy}" />
<DataGridTextColumn Header="LastModifiedAt" Binding="{Binding LastModifiedAt, Converter={StaticResource dateTimeConverter}}" />
</DataGrid.Columns>
</DataGrid>
</baseView:PageViewBase>
</UserControl>
上面的孩子的xaml代码是到目前为止我所管理的最好的代码,但最终只显示列(例如,从基础上没有工具栏),并且从基础视图中看不到UserControl.Resources
。我该如何运作?
答案 0 :(得分:0)
这是一个使用后台代码将正确的列动态添加到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
中正确地获得了不同的列集。但是,我还没有在更复杂的情况下尝试过此操作,因此如果无法解决您的特定问题,我会向您道歉。