【问题标题】:WPF GridSplitter behavior when resizing its parent Window调整其父窗口大小时的 WPF GridSplitter 行为
【发布时间】:2013-03-17 20:09:06
【问题描述】:

我已经定义了我的 GridSplittler XAML,如下所示。

<Window>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
    </Grid>

    <Border Grid.Column="0" Background="Red" />
    <GridSplitter Grid.Column="1" ResizeDirection="Columns" Width="3" Height="Auto" HorizontalAlighment="Stretch" VerticalAlignment="Stretch" />
    <Border Grid.Column="0" Background="Green" />

</Window>

这将创建两列,它们之间有一个网格拆分器,并且它会在左右拖动网格拆分器时正确调整列的大小。现在,如果您调整整个窗口的大小,我希望左侧红色列的宽度保持固定,并且右侧绿色列的宽度会发生变化(随着窗口大小的调整)。它与调整整个 Visual Studio 应用程序的大小时效果相同,并且解决方案资源管理器的宽度保持固定,但代码选项卡的宽度会发生变化。也与 SQL Server Management Studio 相同;对象资源管理器的宽度保持固定,但 SQL 选项卡的宽度会发生变化。我意识到这两个示例使用了更复杂的停靠控件,但我希望使用 WPF GridSplitter 获得相同的结果。

编辑:根据 mathieu 的建议,所有必要的就是给第一列定义一个初始宽度(下面使用 200 显示)。

<Grid Name="GridName">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="200" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0" Background="Red" />
    <GridSplitter Name="SplitterName" Grid.Column="1" ResizeDirection="Columns" Width="3" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    <Border Grid.Column="2" Background="Green" />
</Grid>

现在,当重新调整窗口大小时,它只会改变绿色边框的宽度,而红色边框的宽度保持不变。谢谢!

【问题讨论】:

    标签: wpf resize window gridsplitter


    【解决方案1】:

    我使用了 mathieu 的代码片段 - 并对其进行了修改以供后面使用的代码使用。 在我的情况下,我需要由 GridSplitter 调整大小的动态项目数。

    我使用拇指控件来完全控制操作

    private Thumb GetNewThumbAsGridSplitter(int column)
        {
            var gs = new Thumb();
            gs.SetValue(Grid.ColumnProperty, column);
            // gs.SetValue(Grid.RowSpanProperty, 2);
            // gs.SetValue(Grid.RowProperty, 1);
            gs.Width = 5;
            gs.MouseEnter += (o, i) =>
            {
                Mouse.OverrideCursor = Cursors.ScrollWE;
            };
            gs.MouseLeave += (o, i) =>
            {
                Mouse.OverrideCursor = Cursors.Arrow;
            };
            gs.DragDelta += (o, i) =>
            {
                var grid = (Grid)gs.Parent;
                var previous = (YourControl)((grid.Children[column - 1]));
                var next = (YourControl)(grid.Children[column + 1]);
    
                if (next.MinWidth >= (next.ActualWidth - i.HorizontalChange))
                {
                    return;
                }
    
                if (previous.MinWidth >= (previous.ActualWidth + i.HorizontalChange))
                {
                    return;
                }
    
                previous.Width = previous.ActualWidth + i.HorizontalChange;
                next.Width = next.ActualWidth - i.HorizontalChange;
            };
    
            return gs;
        }
    

    【讨论】:

      【解决方案2】:

      如果您不介意后面的一些代码,您可以通过对拆分器的 DragDelta 事件做出反应,调整第一列的宽度,移除星形宽度,并根据拖动增量。

      Xaml:

      <Grid Name="GridName">
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*" />
              <ColumnDefinition Width="Auto" />
              <ColumnDefinition Width="*" />
          </Grid.ColumnDefinitions>
          <Border Grid.Column="0" Background="Red" />
          <GridSplitter Name="SplitterName" Grid.Column="1" ResizeDirection="Columns" Width="3" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
          <Border Grid.Column="2" Background="Green" />
      </Grid>
      

      后面的代码

      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
      
              SplitterName.DragDelta += SplitterNameDragDelta;
          }
      
          private void SplitterNameDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
          {
              GridName.ColumnDefinitions[0].Width = new GridLength(GridName.ColumnDefinitions[0].ActualWidth + e.HorizontalChange);
          }
      }
      

      【讨论】:

      • 感谢您的回复。我测试了您的解决方案,它似乎只有在网格拆分器至少被拖动一次时才有效。如果您运行应用程序并立即重新调整窗口大小,则左列不会保持固定不变。如果您在重新调整窗口大小之前运行该应用程序并至少拖动一次网格拆分器,那么它会使左列保持固定宽度。
      • 嘿,mathieu,再次感谢。据我所知,在 InitializeComponent() 之后的 ColumnDefinition 的 ActualWidth 为零,因此在应用程序启动时它根本不显示左边框。您的建议是给 ColumnDefinition 一个初始宽度,因此我将第一个 Column Definition 的宽度从 * 更改为某个初始宽度,例如 200。现在网格拆分器后面没有任何代码可以按照我的需要运行。谢谢!
      猜你喜欢
      • 2012-01-28
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2011-10-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多