2014-10-29 69 views
1

我正在寻找以水平方式显示动态数量的按钮,以便它们总是水平填充空间,无论有多少物品。横向拉伸物品

例如,当有两个按钮

__________________________________ 
| other controls     | 
|        | 
|________________________________| 
| Button 1 | Button 2 | Button 3 | 
---------------------------------- 

和按钮2获取隐藏(折叠),这应该成为

__________________________________ 
| other controls     | 
|        | 
|________________________________| 
| Button 1 | Button 3 | 
---------------------------------- 

这可能与WinRT中/ WP 8.1 XAML?

+0

难道你还尝试过什么? – xmashallax 2014-10-29 10:49:36

+0

是的,几乎所有我可以通过搜索网络和SO找到。水平的堆叠面板,带有堆叠面板的列表视图,具有自动/ 1 *列宽度的不同组合的网格,... – koenmetsu 2014-10-29 10:51:25

+0

我也推送它也;)但拆分面板的选项?请参阅此处的参考http://developer.nokia.com/community/wiki/Tabbed_interface_with_Pivot_animation_for_Windows_Phone – Depechie 2014-10-29 12:21:52

回答

3

我会使用网格并将列宽设置为零以隐藏它。由于所有其他列都有星号值,因此它们应该相应地延伸如果一切都失败,您可以手动重新计算星形值,因为您知道可见按钮的数量。

样品:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="50" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 

    <Button Grid.Column="0" Content="Foo" Margin="0,0,0,0" HorizontalAlignment="Stretch" /> 
    <Button Grid.Column="1" Content="Foo" Margin="0,0,0,0" HorizontalAlignment="Stretch" /> 
    <Button Grid.Column="2" Content="Foo" Margin="0,0,0,0" HorizontalAlignment="Stretch" /> 
</Grid> 

设置一列的ColumnDefinition到零并且该按钮被隐藏,其它列相应的调整。

+0

这很简单,效果很好。我已经使用BooleanToGridLengthConverter将宽度绑定到布尔值,以使其更具动态性。 – koenmetsu 2014-10-29 13:16:35

1

您可以始终从Panel派生出您自己的自定义布局逻辑。以下是我想出了:

StretchPanel.cs

class StretchPanel : Panel 
{ 
    #region Properties 

    public bool EqualWidths 
    { 
     get { return (bool)GetValue(EqualWidthsProperty); } 
     set { SetValue(EqualWidthsProperty, value); } 
    } 

    public static readonly DependencyProperty EqualWidthsProperty = 
     DependencyProperty.Register("EqualWidths", typeof(bool), typeof(StretchPanel), new PropertyMetadata(false, onEqualWidthsChanged)); 

    #endregion 

    static void onEqualWidthsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var panel = (StretchPanel)d; 
     panel.InvalidateMeasure(); 
     panel.InvalidateArrange(); 
    } 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     var renderedChildren = Children.Where(c => c.Visibility == Visibility.Visible); 
     var count = renderedChildren.Count(); 

     Size childAvailableSize = availableSize; 
     if (EqualWidths) 
      childAvailableSize = new Size(availableSize.Width/count, availableSize.Height); 

     foreach (var child in renderedChildren) 
      child.Measure(childAvailableSize); 

     var totalHeight = renderedChildren.Max(c => c.DesiredSize.Height); 
     return new Size(availableSize.Width, totalHeight); 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     var renderedChildren = Children.Where(c => c.Visibility == Visibility.Visible); 
     var count = renderedChildren.Count(); 
     var equalWidth = finalSize.Width/count; 

     var totalWidth = renderedChildren.Sum(c => c.DesiredSize.Width); 
     var totalHeight = renderedChildren.Max(c => c.DesiredSize.Height); 

     var x = 0.0; 

     foreach (var child in renderedChildren) 
     { 
      var r = new Rect(); 
      r.X = x; 
      r.Y = 0; 
      r.Width = EqualWidths ? equalWidth : child.DesiredSize.Width/totalWidth * finalSize.Width; 
      r.Height = child.DesiredSize.Height; 

      child.Arrange(r); 

      x += r.Width; 
     } 

     return new Size(finalSize.Width, totalHeight); 
    } 
} 

您可以使用它像这样:

<Page 
    x:Class="App19.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App19" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 

    <Page.Resources> 
     <Style TargetType="Button"> 
      <Setter Property="HorizontalAlignment" Value="Stretch" /> 
      <Setter Property="MinWidth" Value="0" /> 
     </Style> 
     <Style TargetType="TextBlock"> 
      <Setter Property="FontSize" Value="16" /> 
      <Setter Property="Foreground" Value="Yellow" /> 
      <Setter Property="Margin" Value="0,10,0,0" /> 
     </Style> 
    </Page.Resources> 

    <StackPanel> 
     <TextBlock>Different widths</TextBlock> 
     <local:StretchPanel EqualWidths="False"> 
      <Button>a</Button> 
      <Button>big</Button> 
      <Button>purple</Button> 
      <Button>dishwasher</Button> 
     </local:StretchPanel> 

     <TextBlock>Equal widths</TextBlock> 
     <local:StretchPanel EqualWidths="True"> 
      <Button>a</Button> 
      <Button>big</Button> 
      <Button>purple</Button> 
      <Button>dishwasher</Button> 
     </local:StretchPanel> 

     <TextBlock>Different widths, one child hidden</TextBlock> 
     <local:StretchPanel EqualWidths="False"> 
      <Button>a</Button> 
      <Button>big</Button> 
      <Button Visibility="Collapsed">purple</Button> 
      <Button>dishwasher</Button> 
     </local:StretchPanel> 

     <TextBlock>Equal widths, one child hidden</TextBlock> 
     <local:StretchPanel EqualWidths="True"> 
      <Button>a</Button> 
      <Button>big</Button> 
      <Button Visibility="Collapsed">purple</Button> 
      <Button>dishwasher</Button> 
     </local:StretchPanel> 
    </StackPanel> 
</Page> 

而且截图:

Screenshot

+0

我试过类似的SplitPanel @depechie链接,但在我的情况下,MeasureOverride似乎发生在儿童仍然可见时折叠。 – koenmetsu 2014-10-29 13:21:58