水平拉伸水平方向的项目

时间:2014-10-29 10:28:47

标签: xaml windows-phone winrt-xaml windows-phone-8.1

我希望以水平方式显示动态数量的按钮,这样无论有多少项目,它们总是水平填充空间。

例如,当有两个按钮

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

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

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

这可能与Winrt / WP 8.1 xaml一起使用吗?

2 个答案:

答案 0 :(得分: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设置为零,该按钮被隐藏,其他列也相应调整。

答案 1 :(得分: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