当网格 (usercontrol/window) 大小改变时,带有固定面板(网格列)的 GridSplitter

GridSplitter with a fixed panel (grid column) when grid (usercontrol/window) size changes

基本上,我想模拟 WinForms 中可用的 GridSplitter.FixedPanel 功能。

XAML :

<UserControl ...>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4*" />
            <ColumnDefinition Width="3" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <ListBox Grid.Column="0" />
        <GridSplitter 
            Grid.Column="1" Width="3" VerticalAlignment="Stretch" 
            Background="Transparent" 
            ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" />
        <ListBox Grid.Column="2" />
    </Grid>
</UserControl>

这很好用,可以相应地调整每一边的大小。但是假设我们调整包含此 UserControl 的(未最大化)window 的大小,现在拆分器(自动)两侧的两个网格列都会调整大小。开始时 space 分配需要 4/5 和 1/5 的列宽比,但实际 space 分配取决于显示的数据,因此网格拆分器。

如何使一列保持其宽度(例如右侧的一列,因为它包含属性、工具等)而 window 调整大小,因此只调整左列的大小。

我有一些想法:

  1. 只需隐藏代码即可像在 WinForms 中一样模拟 FixedPanel:DragStarted、DragCompleted 和一些私有字段,例如
  2. SO topic 中建议的那样使用 Behavior(我已经很多年没有使用行为了,需要做一些令人耳目一新的事情 - 老实说,我真的希望有一个 XAML-唯一的方式,但如果没有,我更喜欢我公开新的依赖属性而不是行为的代码隐藏方式)
  3. 我相信我缺少 WPF 的一项功能来实现此 WPF 方式。几乎所有时候我都在想 “嗯,我想我必须 代码背后 这个...”,有 WPF 方式,通常更简单,更安全,易于设计,性能更好。这就是我直接询问的原因,也许会帮助其他人寻找该功能。

编程语言(就此而言):C#


编辑:在 Léo Savador 的回答之后:

请参阅: WPF 方式(玩弄 XAML ColumnDefinition Width 属性)和少量代码:

bool p_layoutInitialized = false;
void UserControl_SizeChanged(object sender, SizeChangedEventArgs e) {
    if (e.NewSize.Width > 1) { // optional : && e.NewSize.Height > 1
        if (!p_layoutInitialized) {
            RightColumn.Width = new GridLength(MainGrid.ActualWidth / 5);
            p_layoutInitialized = true;
        }
    }
}

其中 RightColumn 是右侧 ColumnDefinition 的名称,MainGridGrid.

的名称

非常感谢,正在后面写重代码。你节省了我很多时间 :D


PS : 请不要假设我是 WinForm 迷。我只是提到 WinForms 来给出所需功能的比较示例,可以使用 CSS 和 JS,但更难描述。

这里有一个简单的解决方案,我可以根据您的需要推荐给您:

对于您的右栏,不要使用动态宽度 (1*),而是使用固定宽度:

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="3" />
            <ColumnDefinition Width="160" />
        </Grid.ColumnDefinitions>

如果您将固定宽度设置为 160:

  • 您将获得相同的初始结果(window 初始宽度的 1/5)
  • 您仍然可以调整网格大小
  • 调整大小时,右栏将保持其宽度

而且你也有可能在启动时使用代码隐藏来计算所需的固定宽度,根据window初始宽度,更“动态”。