在WPF中调整窗口大小时,负边距控件会被剪裁

时间:2016-06-25 08:39:52

标签: wpf resize margin negative-number clipped

我尝试理解为什么在减小主窗口宽度时会修剪边框元素。 请看下面的代码块。

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="500" Name="MainWin">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <Border Background="Blue" Grid.Row="0" BorderBrush="Black" Width="{Binding ElementName=MainWin, Path=Width}" />
        <Grid Grid.Row="1" Margin="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="0" Background="Black">
                <Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2"
                        Margin="0,-100,0,0">

                    <TextBlock Text="{Binding ElementName=MainWin, Path=Width}" FontSize="14" FontWeight="Bold"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center" />

                </Border>
            </StackPanel>
            <StackPanel Grid.Column="1" Background="Red" />
            <StackPanel Grid.Column="2" Background="Yellow" />
        </Grid>
    </Grid>
</Window>

以下是原始窗口宽度中出现的边框:

未调整大小的窗口

enter image description here

正如您所看到的那样,由于上边距为负,边框显示在其容器外部,在这种情况下为-100。这是我期望的边境。但是当我减小主窗口宽度到达红色矩形的右边缘时,边框的外侧部分会被剪裁。

调整大小的窗口

enter image description here

我尝试将此border元素放在自定义StackPanel中,该StackPanel会覆盖ArrangeOverride,MeasureOverride和GetLayoutClip方法,但遗憾的是,在调整主窗口大小时不会调用这些方法。

如果有人能解释我的原因是什么以及如何解决这个问题,我感激不尽。 非常感谢。

2 个答案:

答案 0 :(得分:0)

  1. 您将蓝色边框的Width绑定到MainWindow的Width。 对于将来:如果要绑定到FrameworkElement属性的任何ActualWidth绑定的宽度。

  2. WPF绘制其内容的顺序完全取决于包含控件。我会说在你的情况下,外部Grid按照定义的顺序绘制需要更新的子。所以只要内部网格随边框变化,你就会很高兴。只要第三列的Width发生变化,就是这种情况。一旦它为0,就没有更多变化,因此不会更新。

  3. (2)是推测=)

  4. 不做(1),不需要它

  5. 使用一个网格

  6. 一些XAML:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>        
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
        <Border Background="Blue" BorderBrush="Black" Grid.ColumnSpan="3"/>
        <StackPanel Grid.Column="0" Grid.Row="1" Background="Black" >
          <Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2"  Margin="0,-100,0,0">
            <TextBlock Text="{Binding ElementName=MainWin, Path=ActualWidth}" FontSize="14" FontWeight="Bold"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center" />
          </Border>
        </StackPanel>
        <StackPanel Grid.Column="1" Grid.Row="1" Background="Red" />
        <StackPanel Grid.Column="2" Grid.Row="1" Background="Yellow" />          
    </Grid>
    

答案 1 :(得分:0)

根据对@Marks的解释,这是我的解决方案

  1. 创建自定义网格并覆盖MeasureOverride方法
  2. 用此自定义网格替换内部网格
  3. CustomGrid类

    public class CustomGrid : Grid
    {
        private double _originalHeight = 0;
    
        protected override Size MeasureOverride(Size constraint)
        {
            Size? size = null;
            if (constraint.Width <= 300)
            {
                size = new Size(constraint.Width, _originalHeight);
            }
            else
            {
                size = base.MeasureOverride(constraint);
                _originalHeight = constraint.Height;
    
            }
            return size.Value;
        }
    
    }
    

    XAML代码

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication1="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="300" Width="500" Name="MainWin">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <Border Background="Blue" Grid.Row="0" BorderBrush="Black" Width="{Binding ElementName=MainWin, Path=Width}" />
        <wpfApplication1:CustomGrid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="150" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <StackPanel Grid.Column="0" Background="Black">
                <Border Background="White" Width="150" Height="150" BorderBrush="Black" BorderThickness="2"
                        Margin="0,-100,0,0">
    
                    <TextBlock Text="{Binding ElementName=MainWin, Path=Width}" FontSize="14" FontWeight="Bold"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Bottom" />
    
                </Border>
            </StackPanel>
            <StackPanel Grid.Column="1" Background="Red" />
            <StackPanel Grid.Column="2" Background="Yellow" />
        </wpfApplication1:CustomGrid>
    </Grid>