ItemsControl 和 ScrollViewer 中的 WPF Grid.IsSharedSizeScope
WPF Grid.IsSharedSizeScope in ItemsControl and ScrollViewer
我只是在使用 this 日志查看器。它基本上按预期工作,但不知何故列长度不共享相同的大小。
这是我的代码:
<Window.Resources>
<local:IsGreaterThanConverter x:Key="IsGreaterThanConverter" />
<sys:Int32 x:Key="MaxDisplayLineLength">200</sys:Int32>
<Style TargetType="ItemsControl" x:Key="LogViewerStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type logging:LogEntry}">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Name="Date" Text="{Binding DateTime, StringFormat={}{0:yyyy.MM.dd HH:mm:ss}}" Grid.Column="0" FontWeight="Bold" Margin="5,0,5,0"/>
<TextBlock Name="Index" Text="{Binding Index, StringFormat=({0})}" Grid.Column="1" FontWeight="Bold" Margin="0,0,2,0" TextAlignment="Left" />
<TextBlock Name="Line" Text="{Binding Line}" Grid.Column="2" TextWrapping="NoWrap" Margin="5,0,5,0"/>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Source}" Value="LUA">
<Setter Property="Grid.Background" Value="White"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Source}" Value="PYTHON">
<Setter Property="Grid.Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
<!--
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Line.Length, Converter={StaticResource IsGreaterThanConverter}, ConverterParameter={StaticResource MaxDisplayLineLength}}" Value="True">
<Setter TargetName="Line" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
-->
</DataTemplate>
</Window.Resources>
<Grid>
<!-- -->
<ItemsControl ItemsSource="{Binding LuaLog.Data, Mode=OneWay}" Style="{StaticResource LogViewerStyle}" Grid.IsSharedSizeScope="True">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" utils:AutoScrollBehavior.AutoScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
我没有找到任何与此问题相关的帖子,可能是因为我不知道哪些控件与此问题相关。
我尝试将 Grid.IsSharedSizeScope 添加到以下位置:
- 最上面的网格
- 项目控制
- 滚动查看器
- ItemsPresenter
没有任何结果:
我必须在哪里添加 Grid.IsSharedSizeScope 才能使其正常工作?有类似情况的经验法则吗?
编辑: Andy-s 解决方案有效。
对子孙后代的一些 警告 :即使只有 100 行,它也会大大减慢执行速度。可能是因为 space 计算。我将使用固定的列宽。
解决方案如下所示(不要忘记从 ItemTemplate Grid 中删除 Grid.IsSharedSizeScope)
<ItemsControl ItemsSource="{Binding LuaLog.Data, Mode=OneWay}" Style="{StaticResource LogViewerStyle}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type logging:LogEntry}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
...
我认为您的问题是在 itemscontrol 之外定义数据模板。
据我了解,范围适用于控件内的所有内容。您的数据模板不是,因此可能只是 "outside" 那个范围。
当我使用 sharedsizescope 时,我总是使用 itemtemplate 或 itemscontrol.resources。
我也会让你的最后一列宽度 * 所以它会占用所有结束的 space。
无论如何,这是我的一些实时标记:
<ItemsControl ItemsSource="{Binding}" Grid.IsSharedSizeScope="True"
IsTabStop="False"
>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="sharedWidth"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
我只是在使用 this 日志查看器。它基本上按预期工作,但不知何故列长度不共享相同的大小。
这是我的代码:
<Window.Resources>
<local:IsGreaterThanConverter x:Key="IsGreaterThanConverter" />
<sys:Int32 x:Key="MaxDisplayLineLength">200</sys:Int32>
<Style TargetType="ItemsControl" x:Key="LogViewerStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type logging:LogEntry}">
<Grid IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Name="Date" Text="{Binding DateTime, StringFormat={}{0:yyyy.MM.dd HH:mm:ss}}" Grid.Column="0" FontWeight="Bold" Margin="5,0,5,0"/>
<TextBlock Name="Index" Text="{Binding Index, StringFormat=({0})}" Grid.Column="1" FontWeight="Bold" Margin="0,0,2,0" TextAlignment="Left" />
<TextBlock Name="Line" Text="{Binding Line}" Grid.Column="2" TextWrapping="NoWrap" Margin="5,0,5,0"/>
<Grid.Style>
<Style TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Source}" Value="LUA">
<Setter Property="Grid.Background" Value="White"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=Source}" Value="PYTHON">
<Setter Property="Grid.Background" Value="LightGray"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
</Grid>
<!--
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Line.Length, Converter={StaticResource IsGreaterThanConverter}, ConverterParameter={StaticResource MaxDisplayLineLength}}" Value="True">
<Setter TargetName="Line" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
-->
</DataTemplate>
</Window.Resources>
<Grid>
<!-- -->
<ItemsControl ItemsSource="{Binding LuaLog.Data, Mode=OneWay}" Style="{StaticResource LogViewerStyle}" Grid.IsSharedSizeScope="True">
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer CanContentScroll="True" HorizontalScrollBarVisibility="Visible" utils:AutoScrollBehavior.AutoScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
我没有找到任何与此问题相关的帖子,可能是因为我不知道哪些控件与此问题相关。 我尝试将 Grid.IsSharedSizeScope 添加到以下位置:
- 最上面的网格
- 项目控制
- 滚动查看器
- ItemsPresenter
没有任何结果:
我必须在哪里添加 Grid.IsSharedSizeScope 才能使其正常工作?有类似情况的经验法则吗?
编辑: Andy-s 解决方案有效。
对子孙后代的一些 警告 :即使只有 100 行,它也会大大减慢执行速度。可能是因为 space 计算。我将使用固定的列宽。
解决方案如下所示(不要忘记从 ItemTemplate Grid 中删除 Grid.IsSharedSizeScope)
<ItemsControl ItemsSource="{Binding LuaLog.Data, Mode=OneWay}" Style="{StaticResource LogViewerStyle}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type logging:LogEntry}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Date" Width="Auto"/>
<ColumnDefinition SharedSizeGroup="Index" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
...
我认为您的问题是在 itemscontrol 之外定义数据模板。 据我了解,范围适用于控件内的所有内容。您的数据模板不是,因此可能只是 "outside" 那个范围。
当我使用 sharedsizescope 时,我总是使用 itemtemplate 或 itemscontrol.resources。
我也会让你的最后一列宽度 * 所以它会占用所有结束的 space。
无论如何,这是我的一些实时标记:
<ItemsControl ItemsSource="{Binding}" Grid.IsSharedSizeScope="True"
IsTabStop="False"
>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="sharedWidth"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>