如何让网格子项(边框)在设置为 0 像素后跟随列调整大小?

问题描述 投票:0回答:1

背景:在网格中,我有两个带有 GridSplitter 的面板,用于调整它们的大小,以及一个用于切换左侧面板折叠或展开的按钮。

未折叠时行为正确。

折叠时,如果我使用 GridSplitter,左侧面板保持为 0 像素,但我希望它遵循 GridSplitter 完成的调整大小。

如何实现这一目标? 看来我可以使用 GridSplitter 的事件,但是是哪一个,以及如何使用?拖动*鼠标*?

我有一个用户控件:

<UserControl x:Class="SublimeTriptych.control.Repro"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:SublimeTriptych.control"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid Name="ContainerGrid">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="160"/>
            <ColumnDefinition Width="4"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Border Grid.ColumnSpan="1" Background="Gold"
                Visibility="{Binding PanelVisibility, Mode=OneWay, RelativeSource={RelativeSource AncestorType=local:Repro}}"/>
        <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
        <Border Grid.Column="2" Background="Orange"/>

        <DockPanel Grid.ColumnSpan="3" Grid.Column="0" VerticalAlignment="Bottom">
            <Button HorizontalAlignment="Center" Command="{Binding SwitchVisibilityCommand, RelativeSource={RelativeSource AncestorType=local:Repro}}">👁</Button>
        </DockPanel>
    </Grid>
</UserControl>

背后的代码:

public partial class Repro : INotifyPropertyChanged
{
    private ICommand? _switchVisibilityCommand;
    private Visibility _panelVisibility = Visibility.Visible;
    private GridLength _videoPanelWidth;
    private GridLength _propPanelWidth;

    public Repro()
    {
        InitializeComponent();
    }

    public ICommand SwitchVisibilityCommand => _switchVisibilityCommand ?? (_switchVisibilityCommand =
        new DelegateCommandListen(
            s =>
            {
                PanelVisibility = PanelVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
                if (PanelVisibility == Visibility.Collapsed)
                {
                    _propPanelWidth = ContainerGrid.ColumnDefinitions[0].Width;
                    _videoPanelWidth = ContainerGrid.ColumnDefinitions[2].Width;
                    ContainerGrid.ColumnDefinitions[0].Width = new GridLength(0, GridUnitType.Pixel);
                    ContainerGrid.ColumnDefinitions[2].Width = new GridLength(1, GridUnitType.Star);
                }
                else
                {
                    ContainerGrid.ColumnDefinitions[2].Width = _videoPanelWidth;
                    ContainerGrid.ColumnDefinitions[0].Width = _propPanelWidth;
                }
            },
            s => true));

    public Visibility PanelVisibility
    {
        get => _panelVisibility;
        set => SetField(ref _panelVisibility, value);
    }

    #region inpc

    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    #endregion
}
c# wpf xaml
1个回答
0
投票

您的用户控件不必要地复杂。您不需要仅仅为了更改其内部元素的外观而使用具有属性和命令的绑定。

要管理左列的宽度,更改其ColumnWidth会更容易。

<UserControl x:Class="SublimeTriptych.Control.Repro"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="LeftColumn" Width="160"/>
                <ColumnDefinition Width="4"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Border Grid.Column="0" Background="Gold"/>
            <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
            <Border Grid.Column="2" Background="Orange"/>
        </Grid>

        <DockPanel VerticalAlignment="Bottom">
            <Button HorizontalAlignment="Center" Click="Button_Click">👁</Button>
        </DockPanel>
    </Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;

public partial class Repro : UserControl
{
    public Repro()
    {
        InitializeComponent();
    }

    private double _leftColumnWidth;

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (this.LeftColumn.ActualWidth > 0)
        {
            _leftColumnWidth = this.LeftColumn.ActualWidth;
            this.LeftColumn.Width = new GridLength(0);
        }
        else
        {
            this.LeftColumn.Width = new GridLength(_leftColumnWidth);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.