内部是不是有任何自动调整项目大小的控件
Posted
技术标签:
【中文标题】内部是不是有任何自动调整项目大小的控件【英文标题】:Is there any control for auto resize items inside内部是否有任何自动调整项目大小的控件 【发布时间】:2017-02-10 01:07:39 【问题描述】:是否有任何控件可以自动调整内部项目的大小。我只需要在一行中包含 ItemsControl 内的文本块,因此如果总项目宽度大于 container.Width,它将改变每个项目的宽度。 UWP
<ItemsControl Grid.Column="1"
ItemsSource="Binding Path=NavigationHistory, ElementName=Main, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged"
x:Name="BroadComb"
MaxHeight="24"
Margin="10,0,0,0" VerticalAlignment="Center" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<HyperlinkButton Command="Binding Path=NavigateCommand, ElementName=Main" CommandParameter="Binding" Margin="10,0,0,0" Foreground="ThemeResource AppAccentForegroundLowBrush" >
<HyperlinkButton.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center"
TextTrimming="None"
Text="Binding Path=DisplayName"
FontSize="10"
FontWeight="Bold"
Foreground="ThemeResource AppAccentForegroundLowBrush">
<i:Interaction.Behaviors>
<core:DataTriggerBehavior Binding="Binding Path=CanBeTrim" Value="True">
<core:ChangePropertyAction PropertyName="TextTrimming" Value="WordEllipsis"/>
</core:DataTriggerBehavior>
<core:DataTriggerBehavior Binding="Binding Path=CanBeTrim" Value="False">
<core:ChangePropertyAction PropertyName="TextTrimming" Value="None"/>
</core:DataTriggerBehavior>
</i:Interaction.Behaviors>
</TextBlock>
<FontIcon Margin="10,0,0,0" HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="ms-appx:/Assets/Fonts/MyBook-Regular.ttf#MyBook"
FontSize="10"
Glyph="2" Foreground="ThemeResource AppAccentForegroundLowBrush" />
</StackPanel>
</DataTemplate>
</HyperlinkButton.ContentTemplate>
</HyperlinkButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
【问题讨论】:
【参考方案1】:一种可能性是使用Grid
,并在其列中将所需控件设置为HorizontalAlignment="Stretch"
:
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="abc" HorizontalAlignment="Stretch" />
<TextBlock Grid.Column="1" Text="xyz" HorizontalAlignment="Stretch" />
</Grid>
这将根据 Grid 的容器将两个控件拉伸到最大可用宽度,并在可用空间发生变化时使它们变小或变大。
大多数情况下,您只想将一列设置为填充可用空间 (Width="*"),并将其他列设置为固定或相对宽度。您可以尝试这些设置。
否则,我们需要更准确地说明您想要实现的目标。
【讨论】:
我已经绑定到 itemssource,并且当总宽度超过 itemscontrol 时需要折叠一些 textblock.text 以修剪文本。 所以你有一个绑定到字符串列表的 ItemsSource?这个 ItemsSouce 的 ItemTemplate 是 TextBlock 吗?那些应该堆在一起排成一行?您能否使用示例代码扩展您的问题,显示您正在尝试做什么? 感谢代码示例。现在很清楚您如何以及为什么需要它。不幸的是,我不知道有任何开箱即用的控件可以在 UWP 中执行此操作。需要注意的是调整所有堆叠元素的大小,但也要相对于它们的原始大小。我担心这里需要一个支持这一点的自定义控件。也许其他人可以提出解决方案,但我会考虑一下,稍后可能会回复您。 感谢您的来信。如果您有任何想法,我们会很高兴。【参考方案2】:是否有任何控件可以自动调整内部项目的大小。我只需要在一行中包含 ItemsControl 内的文本块,因此如果总项目宽度大于 container.Width,它将改变每个项目的宽度。 UWP
你需要改变GridView的默认ItemsPanel
。您可以创建自己的自定义面板,让文本仅排列在一行中:
创建您自己的自定义面板OneRowPanel.cs
:
public class OneRowPanel:Panel
double itemHeight=0;
protected override Size MeasureOverride(Size availableSize)
int count = Children.Count;
foreach (FrameworkElement child in Children)
child.Measure(new Size(availableSize.Width/count,availableSize.Height));
if (child.DesiredSize.Height > itemHeight)
itemHeight = child.DesiredSize.Height;
;
// return the size available to the whole panel
return new Size(availableSize.Width, itemHeight);
protected override Size ArrangeOverride(Size finalSize)
// Get the collection of children
UIElementCollection mychildren = Children;
// Get total number of children
int count = mychildren.Count;
// Arrange children
int i;
for (i = 0; i < count; i++)
//get the item Origin Point
Point cellOrigin = new Point(finalSize.Width / count * i,0);
// Arrange child
// Get desired height and width. This will not be larger than 100x100 as set in MeasureOverride.
double dw = mychildren[i].DesiredSize.Width;
double dh = mychildren[i].DesiredSize.Height;
mychildren[i].Arrange(new Rect(cellOrigin.X, cellOrigin.Y, dw, dh));
// Return final size of the panel
return new Size(finalSize.Width, itemHeight);
在您的 Xaml 中使用它并将TextBlock.TextTrimming
设置为CharacterEllipsis
:
<Page
x:Class="AutoResizeItemsSample.MainPage"
...
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="TextTemplate">
<TextBlock Text="Binding Text" TextTrimming="CharacterEllipsis">
</TextBlock>
</DataTemplate>
</Page.Resources>
<Grid Background="ThemeResource ApplicationPageBackgroundThemeBrush">
<StackPanel Name="rootPanel">
<GridView Name="gridView" ItemTemplate="StaticResource TextTemplate" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<local:OneRowPanel ></local:OneRowPanel>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</StackPanel>
</Grid>
</Page>
结果如下:
这里是完整的演示:AutoResizeItemsSample。
【讨论】:
我只需要一行文本块 然后您需要为此创建自己的自定义面板。我已经为此实现了一个简单的自定义面板,请检查新答案。【参考方案3】:使用 ListView 轻松解决这个问题。 ItemsPanel 已经是 StackPanel 并且单个项目将根据需要调整大小。如果您需要每个项目的水平宽度不同,那么开箱即用也支持。我认为解决方案是简单地选择 ListView 控件。
【讨论】:
以上是关于内部是不是有任何自动调整项目大小的控件的主要内容,如果未能解决你的问题,请参考以下文章