【问题标题】: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>

【问题讨论】:

    标签: c# xaml uwp winrt-xaml uwp-xaml


    【解决方案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。您可以创建自己的自定义面板,让文本仅排列在一行中:

    1. 创建您自己的自定义面板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);
          }
      }
      
    2. 在您的 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 控件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多