1

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

    <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>

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

未调整大小的窗口

在此处输入图像描述

如您所见,由于上边距为负,在本例中为 -100,因此边框显示在其容器之外。这是我期望的边界。但是,当我减小主窗口宽度以到达红色矩形的右边缘时,边框的外部部分会被剪裁。

调整大小的窗口

在此处输入图像描述

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

如果有人可以向我解释原因是什么以及如何解决此问题,我将不胜感激。非常感谢。

4

2 回答 2

1

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

  1. 创建自定义网格并覆盖 MeasureOverride 方法
  2. 用这个自定义网格替换内部网格

自定义网格类

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>

于 2016-06-26T04:25:13.323 回答
0
  1. 您将蓝色边框绑定Width到 MainWindow 的Width. 对于未来:如果你想绑定到任何FrameworkElement绑定到其ActualWidth属性的宽度。

  2. WPF 绘制其内容的顺序完全取决于包含控件。我会说在您的情况下,外部会按照定义的顺序Grid绘制需要更新的子代。因此,只要内部网格与边界一起变化,您就可以继续使用。只要Width第三列的 改变,就是这种情况。一旦它为 0,就没有更多的变化,所以它不会被更新。

  3. (2) 是推测 =)

  4. 不要做(1),没有必要

  5. 使用一个网格

一些 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>
于 2016-06-25T09:34:31.843 回答