В моем приложении есть два класса DataObj
и SubDataObj
. Для этих двух классов я хочу создать ListView, в котором я могу редактировать объекты обоих классов. DataObj
содержит List<SubDataObj>
, и некоторые изменения данных влияют на свойства SubDataObj
.
Мой подход заключался в создании моего пользовательского интерфейса следующим образом:
Структурировано так:
Но я не могу выровнять границу 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
само по себе маловато.
заранее спасибо.