简体   繁体   English

UWP:如何根据网格宽度重排控件

[英]UWP: how to reflow controls based on grid width

I have two buttons placed horizontally.我有两个水平放置的按钮。 They are inside a grid.它们位于网格内。 This grid containing two buttons has width 370. When the text on the button becomes large, it needs width more than 370. So what I want to do is, instead of placing then horizontally, I want to place them vertically dynamically when text will start cropping.这个包含两个按钮的网格宽度为 370。当按钮上的文本变大时,它需要超过 370 的宽度。所以我想要做的是,而不是水平放置,我想在文本开始时动态垂直放置它们种植。 Basically, I want auto-reflow behavior inside this grid for these two buttons based on width of the grid (not based on width of main window).基本上,我希望根据网格的宽度(而不是基于主窗口的宽度)在此网格内为这两个按钮自动重排行为。 So I want them to fit in 370 width and if they cannot, I want them to place themselves vertically.所以我希望它们适合 370 宽度,如果它们不能,我希望它们垂直放置。 How can I achieve this?我怎样才能做到这一点?

I explored GridView but it will show buttons inside the box that comes with GridView so I do not want extra UI that comes with GridView unless we have an option to hide it?我探索了 GridView 但它会在 GridView 附带的框内显示按钮,所以我不想要 GridView 附带的额外 UI,除非我们可以选择隐藏它?

I checked AdaptiveTrigger but that is based on width of window not of the control (grid in this case)我检查了 AdaptiveTrigger 但那是基于 window 的宽度而不是控件的宽度(在这种情况下是网格)

<Grid
    Grid.Row="2"
    Margin="0,36,0,28"
    Width="370"
    HorizontalAlignment="Left"
    VerticalAlignment="Bottom">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid
        Grid.Column="0"
        CornerRadius="3">
        <Button
            MinWidth="118"
            MinHeight="30"
            HorizontalAlignment="Left"
            HorizontalContentAlignment="Center"
            VerticalContentAlignment="Center"
            AutomationProperties.Name="{x:Bind ViewModel.PrimaryActionAutomationName, Mode=OneWay}"
            BorderThickness="1"
            Click="{x:Bind ViewModel.InvokePrimaryAction}"
            Content="{x:Bind ViewModel.PrimaryAction, Mode=OneWay}"
            CornerRadius="3"
            Style="{StaticResource AccentButtonStyle}" />
    </Grid>
    <Grid
        Grid.Column="1"
        CornerRadius="3"
        Margin="32,0,0,0">
        <HyperlinkButton
            AutomationProperties.Name="{x:Bind ViewModel.SecondaryLinkAutomationName, Mode=OneWay}"
            AutomationProperties.AutomationId="{Binding AutomationId, ConverterParameter=HyperlinkButton, Converter={StaticResource AutomationIdConverter}}"
            Content="{x:Bind ViewModel.SecondaryText, Mode=OneWay}"
            FontSize="14"
            Margin="0,0,0,0"
            Style="{StaticResource HyperlinkButtonStyle}"
            NavigateUri="{x:Bind ViewModel.SecondaryLink, Mode=OneWay}" />
    </Grid>
</Grid>

For your scenario, I'd suggest you custom a StateTrigger based on the StateTriggerBase Class to monitor the width of the Grid and apply visual states based on the width.对于您的场景,我建议您根据StateTriggerBase Class 自定义一个StateTrigger来监控 Grid 的宽度并根据宽度应用视觉状态。

I've made a simple sample that you could refer to.我制作了一个简单的示例,您可以参考。

ControlSizeTrigger:控件大小触发器:

 public class ControlSizeTrigger : StateTriggerBase
{
    //private variables
    private double _minHeight, _minWidth = -1;
    private FrameworkElement _targetElement;
    private double _currentHeight, _currentWidth;
    //public properties to set from XAML
    public double MinHeight
    {
        get
        {
            return _minHeight;
        }
        set
        {
            _minHeight = value;
        }
    }
    public double MinWidth
    {
        get
        {
            return _minWidth;
        }
        set
        {
            _minWidth = value;
        }
    }
    public FrameworkElement TargetElement
    {
        get
        {
            return _targetElement;
        }
        set
        {
            if (_targetElement != null)
            {
                _targetElement.SizeChanged -= _targetElement_SizeChanged;
            }
            _targetElement = value;
            _targetElement.SizeChanged += _targetElement_SizeChanged;
        }
    }
    //Handle event to get current values
    private void _targetElement_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        _currentHeight = e.NewSize.Height;
        _currentWidth = e.NewSize.Width;
        UpdateTrigger();
    }
    //Logic to evaluate and apply trigger value
    private void UpdateTrigger()
    {
        //if target is set and either minHeight or minWidth is set, proceed
        if (_targetElement != null && (_minWidth > 0 || _minHeight > 0))
        {
            //if both minHeight and minWidth are set, then both conditions must be satisfied
            if (_minHeight > 0 && _minWidth > 0)
            {
                SetActive((_currentHeight >= _minHeight) && (_currentWidth >= _minWidth));
            }
            //if only one of them is set, then only that condition needs to be satisfied
            else if (_minHeight > 0)
            {
                SetActive(_currentHeight >= _minHeight);

            }
            else
            {
                SetActive(_currentWidth >= _minWidth);
                bool bbb = _currentWidth >= _minWidth;
                Debug.WriteLine("Widthtrigger :" + bbb);
            }
        }
        else
        {
            SetActive(false);
        }
    }

}

MainPage.xaml:主页.xaml:

 <Grid>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="ControlSizeStates">
            <VisualState x:Name="SizeChange">
                <VisualState.StateTriggers>
                    <local:ControlSizeTrigger MinWidth="800" TargetElement="{x:Bind Path=MyStackPanel}" />
                    <!--<AdaptiveTrigger MinWindowHeight="500" />-->
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="MyStackPanel.Background" Value="Red" />
                    <Setter Target="MyStackPanel.Orientation" Value="Horizontal" />
                    <Setter Target="MyButton.Foreground" Value="Black" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    
    <StackPanel x:Name="MyStackPanel" Width="100" Height="200" Background="AliceBlue" Orientation="Vertical">
        
       
        <Button x:Name="MyButton" Foreground="Red" Content="Click" Click="Button_Click"/>
        <Button x:Name="MyButton2" Foreground="Red" Content="Click" />
    </StackPanel>
   
</Grid>

MainPage.cs:主页.cs:

  public MainPage()
    {
        this.InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        MyStackPanel.Width = 1100;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM