wpf - WPF SharedSizeGroup 没有正确调整
问题描述
在我的应用程序中,我有两个类 DataObj
和SubDataObj
. 对于这两个类,我想创建一个 ListView,我可以在其中编辑两个类的对象。DataObj
持有 aList<SubDataObj>
和一些数据修改对SubDataObj
属性有影响。
我的方法是像这样构建我的 UI:
结构如下:
但我无法对齐视图的 3 个部分的边框,我无法弄清楚我做错了什么。
父网格有Grid.IsSharedSizeScope="True"
所有ColumnDefinitions
,Grid
代表标题的那些,ListView.DataTemplate
使用的SharedSizeGroup="xxx"
。
我的 XAML 代码如下所示:
<UserControl
x:Class="SharedSizeGroupSandBox.Views.SharedSizeGroupView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SharedSizeGroupSandBox.Views"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:models="clr-namespace:SharedSizeGroupSandBox.Models.SharedSizeGroup"
xmlns:vms="clr-namespace:SharedSizeGroupSandBox.ViewModels"
xmlns:converter="clr-namespace:SharedSizeGroupSandBox.ValueConverter"
mc:Ignorable="d"
d:DesignHeight="450"
d:DesignWidth="800"
d:DataContext="{x:Type vms:SharedSizeGroupVM}">
<UserControl.Resources>
<ResourceDictionary>
<converter:BoolNotConverter
x:Key="BoolNotConverter" />
<Style
x:Key="baseAlignStyle"
TargetType="FrameworkElement">
<Setter
Property="HorizontalAlignment"
Value="Stretch" />
<Setter
Property="VerticalAlignment"
Value="Center" />
</Style>
<Style
x:Key="baseBorderStyle"
TargetType="Border"
BasedOn="{StaticResource baseAlignStyle}">
<Setter
Property="Margin"
Value="0,0" />
</Style>
<Style
x:Key="headerBorderStyle"
TargetType="Border"
BasedOn="{StaticResource baseBorderStyle}">
<Setter
Property="BorderBrush"
Value="Black" />
<Setter
Property="VerticalAlignment"
Value="Stretch" />
<Setter
Property="BorderThickness"
Value="0,0,1,0" />
</Style>
<Style
TargetType="FrameworkElement"
x:Key="baseMargingStyle"
BasedOn="{StaticResource baseAlignStyle}">
<Setter
Property="Margin"
Value="3" />
</Style>
<Style
x:Key="textBlockHeaderStyle"
TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource baseMargingStyle}">
<Setter
Property="TextAlignment"
Value="Center" />
</Style>
<Style
x:Key="checkBoxStyle"
TargetType="CheckBox"
BasedOn="{StaticResource baseMargingStyle}">
<Setter
Property="HorizontalAlignment"
Value="Center" />
</Style>
</ResourceDictionary>
</UserControl.Resources>
<!--#endregion Buttons-->
<ScrollViewer
Grid.Row="1"
HorizontalAlignment="Stretch"
Grid.IsSharedSizeScope="True"
HorizontalScrollBarVisibility="Auto">
<Grid
Grid.Row="1"
HorizontalAlignment="Left"
Margin="0">
<Grid.RowDefinitions>
<RowDefinition
Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--#region Headers-->
<Grid
Margin="0,0,0,0"
Grid.Row="0"
HorizontalAlignment="Left"
x:Name="grdlistHeader">
<Grid.ColumnDefinitions>
<ColumnDefinition
SharedSizeGroup="a" />
<ColumnDefinition
SharedSizeGroup="b" />
<ColumnDefinition
SharedSizeGroup="c" />
<ColumnDefinition
SharedSizeGroup="d" />
<ColumnDefinition
SharedSizeGroup="e" />
<ColumnDefinition
Width="Auto"
SharedSizeGroup="f" />
</Grid.ColumnDefinitions>
<Border
Style="{StaticResource headerBorderStyle}">
<TextBlock
Text="{Binding NameText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="1">
<TextBlock
Text="{Binding DescriptionText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="2">
<TextBlock
Text="{Binding MandatoryText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="3">
<TextBlock
Text="{Binding ObsoleteText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="4">
<TextBlock
Text="{Binding CountryText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Border>
<TextBlock
Grid.Column="5"
Text="{Binding CityText}"
Style="{StaticResource textBlockHeaderStyle}" />
</Grid>
<!--#endregion Headers-->
<ListView
Margin="0,0,0,0"
Padding="0"
Grid.Row="1"
BorderThickness="0,0,0,0"
BorderBrush="Black"
SelectionMode="Single"
SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding Data}"
HorizontalAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden">
<ListView.ItemContainerStyle>
<Style
TargetType="ListViewItem">
<Setter
Property="HorizontalAlignment"
Value="Stretch" />
<Setter
Property="Padding"
Value="0" />
<Setter
Property="Margin"
Value="0" />
<Setter
Property="BorderThickness"
Value="0,1,0,0" />
<Setter
Property="BorderBrush"
Value="Black" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate
DataType="{x:Type vms:DataObjVM}">
<Grid
Margin="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!--#region DataObjVMs-->
<Grid
Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition
SharedSizeGroup="a"
Width="Auto" />
<ColumnDefinition
SharedSizeGroup="b" />
<ColumnDefinition
SharedSizeGroup="c" />
<ColumnDefinition
SharedSizeGroup="d" />
<ColumnDefinition
SharedSizeGroup="e" />
<ColumnDefinition
SharedSizeGroup="f" />
<ColumnDefinition
SharedSizeGroup="g" />
<ColumnDefinition
SharedSizeGroup="h" />
<ColumnDefinition
SharedSizeGroup="i" />
</Grid.ColumnDefinitions>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="0">
<TextBox
Text="{Binding Path=Data.Name, UpdateSourceTrigger=PropertyChanged}"
IsReadOnly="{Binding Path=Obsolete}"
Style="{StaticResource baseMargingStyle}"
Padding="0" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="1">
<TextBox
Text="{Binding Path=Data.Description}"
IsReadOnly="{Binding Path=Obsolete}"
Style="{StaticResource baseMargingStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="2">
<CheckBox
IsEnabled="{Binding Path=Obsolete, Converter={StaticResource BoolNotConverter}}"
IsChecked="{Binding Path=Data.Mandatory}"
Style="{StaticResource checkBoxStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="3">
<CheckBox
x:Name="cbObsolete"
IsChecked="{Binding Path=Obsolete}"
Style="{StaticResource checkBoxStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="4">
<ComboBox
Style="{StaticResource baseMargingStyle}"
ItemsSource="{Binding Countries}"
SelectedItem="{Binding Data.Country}"
DisplayMemberPath="ExternalName"
IsEnabled="{Binding Obsolete, Converter={StaticResource BoolNotConverter}}" />
</Border>
<ComboBox
Grid.Column="5"
Style="{StaticResource baseMargingStyle}"
ItemsSource="{Binding Data.Country.Cities}"
SelectedItem="{Binding Data.City}"
DisplayMemberPath="ExternalName"
IsEnabled="{Binding Obsolete, Converter={StaticResource BoolNotConverter}}" />
</Grid>
<!--#endregion Temmplates-->
<!--#region SubTemmplates-->
<ListView
Margin="0,0,0,0"
BorderThickness="0"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
IsEnabled="{Binding IsEditEnabled}"
Padding="0"
Grid.Row="1">
<ListView.Resources>
<CollectionViewSource
x:Key="SubDataObjs">
<CollectionViewSource.Source>
<Binding
Path="Data.SubDataObjs"
Mode="OneWay"
UpdateSourceTrigger="PropertyChanged" />
</CollectionViewSource.Source>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription
PropertyName="Name"
Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style
TargetType="ListViewItem">
<Setter
Property="HorizontalAlignment"
Value="Stretch" />
<Setter
Property="Padding"
Value="0" />
<Setter
Property="Margin"
Value="0" />
<Setter
Property="BorderThickness"
Value="0,1,0,0" />
<Setter
Property="BorderBrush"
Value="Black" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsSource>
<Binding
Source="{StaticResource SubDataObjs}" />
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate
DataType="{x:Type models:SubDataObj}">
<Grid
Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition
SharedSizeGroup="a" />
<ColumnDefinition
SharedSizeGroup="b" />
<ColumnDefinition
SharedSizeGroup="c" />
<ColumnDefinition
SharedSizeGroup="d" />
<ColumnDefinition
SharedSizeGroup="e" />
<ColumnDefinition
SharedSizeGroup="f" />
<ColumnDefinition
SharedSizeGroup="g" />
<ColumnDefinition
SharedSizeGroup="h" />
<ColumnDefinition
SharedSizeGroup="i" />
</Grid.ColumnDefinitions>
<Border
Style="{StaticResource headerBorderStyle}">
<TextBox
Style="{StaticResource baseMargingStyle}"
Text="{Binding Path=Name}"
IsReadOnly="{Binding Path=Obsolete}"
MaxLength="{Binding MaxNameLength}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="1">
<TextBox
Style="{StaticResource baseMargingStyle}"
IsReadOnly="{Binding Path=Obsolete}"
BorderThickness="1"
Text="{Binding Path=Description}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="2"
Padding="0, 0,0,0">
<CheckBox
IsEnabled="{Binding Path=Obsolete, Converter={StaticResource BoolNotConverter}}"
IsChecked="{Binding Path=Mandatory}"
Style="{StaticResource checkBoxStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="3">
<CheckBox
IsChecked="{Binding Path=Obsolete}"
IsEnabled="{Binding ElementName=cbObsolete, Path=IsChecked, Converter={StaticResource BoolNotConverter}}"
Style="{StaticResource checkBoxStyle}" />
</Border>
<Border
Style="{StaticResource headerBorderStyle}"
Grid.Column="4" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!--#endregion SubTemmplates-->
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</ScrollViewer>
</UserControl>
我已经编写了一个完整的沙盒应用程序,以防它XAML
本身还不够。
先感谢您。
解决方案
制作一个同时包含DataObj
和的集合SubDataObj
。
当您加载数据时,循环遍历每个DataObj
,并为每个将其自身及其所有SubDataObj
s 添加到整个列表中。然后,您可以将法线ListView
与法线一起GridView
使用,并将整体列表用作ItemsSource
.
至于这个“整体收藏”的类型,我看到了三个选项:
DataObj
并且SubDataObj
显然共享一些属性(因为它们都可以显示在同一个网格中),因此它们都从同一个基类继承,或者其中一个继承自另一个可能是有意义的。然后你可以使用SomeCollection<BaseDataObj>
(例如)。- 如果继承不合适,让它们都实现相同的接口,包括它们的共享属性。然后你会使用
SomeBaseCollection<IDataInterface>
(例如)。 - 如果由于某种原因您不想执行上述任何一项操作,只需使用
List<Object>
.
推荐阅读
- javascript - 单击仍带有 $ 符号的按钮时增加数字
- apache-spark - 通过 API 访问 Spark 结果
- android - Android:可打包异常
- php - MySQL在where子句中多次查询同一字段
- .htaccess - htaccess 将 -{dynamic_id}.html 替换为 _i{dynamic_id}
- asp.net-web-api2 - 使用 JWT Bearer 身份验证的 Web API 中的 post 请求中的 Null 有效负载
- sql-server-2008 - 从 SQL 表中的上一行获取值并在下一行的基础上计算
- ios - imagePicker 中的图像不会显示在我的 imageView 中
- sql - Oracle 透视具有相同 ID 的行
- ios - 如何将 PHAsset 存储到核心数据中