2016-06-25 2 views
1

メインウィンドウの幅を小さくすると境界要素がクリップされる理由を理解しようとします。 以下のコードブロックをご覧ください。ここでWPFでウィンドウのサイズを変更すると、ネガティブマージンコントロールがクリップされる

<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。これは私が国境のために持つことを期待しているものです。しかし、メインウィンドウの幅を赤色の矩形の右端まで減らすと、境界線の外側が切り取られます。

私はArrangeOverride、MeasureOverrideとGetLayoutClipメソッドをオーバーライドしていますが、メインウィンドウのサイズが変更されているときに、残念ながら、これらのメソッドが呼び出されていないカスタムのStackPanelの内側に、この境界要素を配置しようとしてい

enter image description here

サイズ変更されたウィンドウ。

誰かが理由を説明でき、この問題を回避する方法を教えていただければ幸いです。 ありがとうございました。

答えて

0

@マークの説明に基づいて、ここに私の解答

  1. このカスタム・グリッドによって、内側グリッドを交換し、カスタム・グリッドを作成し、MeasureOverride方法
  2. をオーバーライド

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> 

0
  1. あなたが結合している青色の境界線のメインウィンドウのWidthからWidth。 今後の場合:FrameworkElementの幅にバインドする場合は、そのActualWidthプロパティにバインドしてください。

  2. WPFがその内容を描画する順序は、コントロールを含むコントロールに大きく依存します。あなたのケースでは、外側Gridは、を定義した順番で更新する必要がある子どもたちを描画します。境界線に沿って内側のグリッドが変化する限り、あなたは良いです。これは、第3列の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> 
+0

Markusの説明をありがとうございます。 1.これは私の例です。私はちょうどボーダーがメインウィンドウの幅を持っていることを望んでいた 2。私はその点を見ることができます。上記の3つのメソッドをオーバーライドするカスタムグリッドを作成しようとしましたが、ウィンドウのサイズが変更されたときに呼び出されます。 3. :) アドバイスありがとう 5.私の実際のアプリケーションの問題は、私の例の場合です。 2つのグリッドが必要です。私が意味するところは、内側のグリッドはユーザコントロールのコンテナです ポイント2の説明に基づいて回避策を見つけます。 –

関連する問題