内部是不是有任何自动调整项目大小的控件

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 控件。

【讨论】:

以上是关于内部是不是有任何自动调整项目大小的控件的主要内容,如果未能解决你的问题,请参考以下文章

将 iOS 项目转换为自动布局

如何在 Qt 设计器中使控件自动调整大小?

控件不适合调整 WPF 的大小

表格调整大小时项目之间的表格布局面板空间

如何自动调整 DataGridView 控件中的列大小并允许用户调整同一网格上的列大小?

在布局之间制作动画时,自动布局不会调整 Uicollectionviewcell 项目的大小