Expanders in Grid

后端 未结 2 1453
野的像风
野的像风 2021-02-01 07:43

This is going to be straight forward no doubt, but for what ever reason, my mind is drawing a blank on it.

I\'ve got a small, non-resizeable window (325x450) which has 3

相关标签:
2条回答
  • 2021-02-01 07:59

    If you don't mind a little code-behind, you could probably hook into the Expanded/Collapsed events, find the parent Grid, get the RowDefinition for the expander, and set the value equal to * if its expanded, or Auto if not.

    For example,

    Expander ex = sender as Expander;
    Grid parent = FindAncestor<Grid>(ex);
    int rowIndex = Grid.GetRow(ex);
    
    if (parent.RowDefinitions.Count > rowIndex && rowIndex >= 0)
        parent.RowDefinitions[rowIndex].Height = 
            (ex.IsExpanded ? new GridLength(1, GridUnitType.Star) : GridLength.Auto);
    

    And the FindAncestor method is defined as this:

    public static T FindAncestor<T>(DependencyObject current)
    where T : DependencyObject
    {
        // Need this call to avoid returning current object if it is the 
        // same type as parent we are looking for
        current = VisualTreeHelper.GetParent(current);
    
        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        };
        return null;
    }
    
    0 讨论(0)
  • 2021-02-01 08:09

    This requirement is a little unusal because the you want the state of the Children in the Grid to decide the Height of the RowDefinition they are in.
    I really like the layout idea though and I can't believe I never had a similar requirement myself.. :)

    For a reusable solution I would use an Attached Behavior for the Grid.
    The behavior will subscribe to the Attached Events Expander.Expanded and Expander.Collapsed and in the event handlers, get the right RowDefinition from Grid.GetRow and update the Height accordingly. It works like this

    <Grid ex:GridExpanderSizeBehavior.SizeRowsToExpanderState="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Expander Grid.Row="0" ... />
        <Expander Grid.Row="1" ... />
        <Expander Grid.Row="2" ... />
        <!-- ... -->
    </Grid>
    

    And here is GridExpanderSizeBehavior

    public class GridExpanderSizeBehavior
    {
        public static DependencyProperty SizeRowsToExpanderStateProperty =
            DependencyProperty.RegisterAttached("SizeRowsToExpanderState",
                                                typeof(bool),
                                                typeof(GridExpanderSizeBehavior),
                                                new FrameworkPropertyMetadata(false, SizeRowsToExpanderStateChanged));
        public static void SetSizeRowsToExpanderState(Grid grid, bool value)
        {
            grid.SetValue(SizeRowsToExpanderStateProperty, value);
        }
        private static void SizeRowsToExpanderStateChanged(object target, DependencyPropertyChangedEventArgs e)
        {
            Grid grid = target as Grid;
            if (grid != null)
            {
                if ((bool)e.NewValue == true)
                {
                    grid.AddHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                    grid.AddHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
                }
                else if ((bool)e.OldValue == true)
                {
                    grid.RemoveHandler(Expander.ExpandedEvent, new RoutedEventHandler(Expander_Expanded));
                    grid.RemoveHandler(Expander.CollapsedEvent, new RoutedEventHandler(Expander_Collapsed));
                }
            }
        }
        private static void Expander_Expanded(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            Expander expander = e.OriginalSource as Expander;
            int row = Grid.GetRow(expander);
            if (row <= grid.RowDefinitions.Count)
            {
                grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Star); 
            }
        }
        private static void Expander_Collapsed(object sender, RoutedEventArgs e)
        {
            Grid grid = sender as Grid;
            Expander expander = e.OriginalSource as Expander;
            int row = Grid.GetRow(expander);
            if (row <= grid.RowDefinitions.Count)
            {
                grid.RowDefinitions[row].Height = new GridLength(1.0, GridUnitType.Auto);
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题