固定大小的GridSplitter MinWidth [英] GridSplitter MinWidth with fixed size

查看:99
本文介绍了固定大小的GridSplitter MinWidth的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有2列的Grid,并使用以下XAML代码将其分隔为GridSplitter:

I have a Grid with 2 columns separated by a GridSplitter using the following XAML code :

<Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="100" MinWidth="20" />
    <ColumnDefinition Width="10" />
    <ColumnDefinition Width="*" MinWidth="100" />
    </Grid.ColumnDefinitions>

    <Rectangle Fill="Blue" />
    <GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch" />
    <Rectangle Fill="Yellow" Grid.Column="2" />
</Grid>

问题:右侧列的MinWidth被忽略

Problem : The MinWidth of the Column on the right is ignored

  • 加载页面时,我绝对需要第一列宽度为"100px",因此它的大小不能为*.
  • 我不想在第一列上设置MaxWidth

*我知道以前已经解决过,但是它总是建议将列大小设置为*或在第一列上设置maxWidth……我不想要那样.

*I know that has been adressed before but it always suggest to set column size to * or set a maxWidth on the first column... I don't want that.

找到了解决方案,但是很丑陋! :p ,有人可以用一种更简洁的方式来实现我想要的... CODELESS(如果可能)吗?

Found a solution, but its UGLY! :p, anybody has a cleaner way to achieve what I want... CODELESS (if possible)?

private void Grid_SizeChanged(object sender, SizeChangedEventArgs e)
{
   var g = (Grid)sender;

   Double maxW = e.NewSize.Width - g.ColumnDefinitions[2].MinWidth - g.ColumnDefinitions[1].ActualWidth;
   g.ColumnDefinitions[0].MaxWidth = maxW;
}

推荐答案

基本问题是网格拆分器通过调整 only 左列的宽度来工作,并假定右列将 > star-size 以适应剩余空间.

The basic problem is that a grid splitter works by adjusting the width of the left column only and assumes the right column will star-size to fit the remaining space.

这意味着您要解决的问题实际上是如何限制左列的最大宽度,以使右列不会变得太小?".基本上,这就是您的代码示例所要做的.

That means the problem you are trying to solve is actually "how do I limit the max width of the left column so that the right column does not get too small?". This is basically what your code sample is doing.

如果您希望可以在XAML中实现的更可移植的解决方案,请创建一个Silverlight

If you want a more portable solution, that you can implement in XAML, create a Silverlight behavior that can be applied to a grid (as shown below). It will attach to the parent grid's SizeChanged event and do pretty much exactly what your code snippet does, but being a behavior you can drag and drop them in Blend or attach them in XAML.

以下是一个示例行为,我将为您提供一个示例(基于您自己的代码):

Here is a sample behavior I threw together for you as an example (based on your own code):

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace GridSplitterMinWidth
{
    public class MinWidthSplitterBehavior : Behavior<Grid>
    {
        public Grid ParentGrid { get; set; }

        protected override void OnAttached()
        {
            base.OnAttached();
            ParentGrid = this.AssociatedObject as Grid;
            ParentGrid.SizeChanged += parent_SizeChanged;
        }

        void parent_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (ParentGrid.ColumnDefinitions.Count == 3)
            {
                Double maxW = e.NewSize.Width - ParentGrid.ColumnDefinitions[2].MinWidth -
                              ParentGrid.ColumnDefinitions[1].ActualWidth;
                ParentGrid.ColumnDefinitions[0].MaxWidth = maxW;
            }
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            if (ParentGrid != null)
            {
                ParentGrid.SizeChanged -= parent_SizeChanged;
            }
        }
    }
}

并像这样使用它:

<UserControl x:Class="GridSplitterMinWidthApp.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:GridSplitterMinWidth="clr-namespace:GridSplitterMinWidth"
    xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" MinWidth="20" />
                <ColumnDefinition Width="10" />
                <ColumnDefinition Width="*" MinWidth="100" />
            </Grid.ColumnDefinitions>
            <interactivity:Interaction.Behaviors>
                <GridSplitterMinWidth:MinWidthSplitterBehavior/>
            </interactivity:Interaction.Behaviors>
            <Rectangle Fill="Blue" />
            <Controls:GridSplitter Grid.Column="1" Background="LightGray" HorizontalAlignment="Stretch">
            </Controls:GridSplitter>
            <Rectangle Fill="Yellow" Grid.Column="2" />
        </Grid>
    </Grid>
</UserControl>

这篇关于固定大小的GridSplitter MinWidth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆