特定の方法で指定された要素を含む 2 つのグリッドと、SharedSizeGroup には少し問題があるようです。
この質問は、私が回答しようとしたユーザー DH からの以前の質問への回答です。長くなってしまいますが、問題を視覚的に示すのに役立ちます。
彼の最初の質問は、SharedSizeGroup を持つ 2 つのグリッドが、特定の条件が満たされたときに同じ高さにサイズ変更されなかった理由 (右側のグリッドで TextBlock のサイズ変更) を尋ねました。私は彼の例を取り上げ、それを拡張しました。なぜなら、それは測定/配置サイクルに関係しているのではないかと疑ったからです。
実際、それはメジャーとアレンジに関係していることがわかりました。実際、それは測定 を行わないことに関係しています。これは、バグではないにしても、少なくとも問題である可能性があると思いますが、動作の説明が必要です.
何が起こるかの簡単な概要を次に示します (デモ用に派手な色を付けています)。
開始
両方のグリッドには 3 つの行があり、それぞれに TextBlock が含まれています。中央の行は SharedSizeGroup のものです。中央の行のテキストは、その TextBlock の ActualHeight にバインドされ、最初の Height プロパティは表示される値にハードコードされています。グリッドの下の数値は、そのグリッドの ActualHeight を表します。左グリッドの BackgroundColor が緑であることに注意してください。
右側のTextBlock を大きくする
右側のグリッドのサイズを大きくすると、SharedSizeGroup により、両方のグリッドが新しい高さにサイズ変更されることがわかります。右側の列は、グリッドの Measure および Arrange 呼び出しを反映しています。
右側のTextBlock
を小さくしても左側の TextBlock よりも大きい場合 右側のグリッドのサイズを小さくしても、左側のハードコードされた TextBlock のサイズよりも大きい場合、両方のグリッドのサイズが再び変更されることがわかります。 SharedSizeGroup により、新しい高さになります。右側の列は、グリッドの Measure および Arrange 呼び出しを反映しています。
右側のTextBlock を左側の
TextBlock のサイズよりも小さくする 右側のグリッドのサイズを縮小すると、左側のハードコーディングされた TextBlock のサイズよりも小さくなります。下部のグリッドの背景が緑色で、グリッドのサイズが 130 ではなく 150 であることからもわかるように、「適切な」サイズに縮小されていません。
右側の情報を見ると、左側のグリッドがアレンジを行ったが、小節を行っていないことがわかります。
問題を再現するためのコード例を次に示します。
InfoGrid および InfoGridEventArgs クラス
using System.Windows;
using System.Windows.Controls;
namespace GridMeasureExample
{
class InfoGrid : Grid
{
protected override Size ArrangeOverride(Size arrangeSize)
{
CallReportInfoEvent("Arrange");
return base.ArrangeOverride(arrangeSize);
}
protected override Size MeasureOverride(Size constraint)
{
CallReportInfoEvent("Measure");
return base.MeasureOverride(constraint);
}
public event EventHandler<InfoGridEventArgs> ReportInfo;
private void CallReportInfoEvent(string message)
{
if (ReportInfo != null)
ReportInfo(this, new InfoGridEventArgs(message));
}
}
public class InfoGridEventArgs : EventArgs
{
private InfoGridEventArgs()
{
}
public InfoGridEventArgs(string message)
{
this.TimeStamp = DateTime.Now;
this.Message = message;
}
public DateTime TimeStamp
{
get;
private set;
}
public String Message
{
get;
private set;
}
}
}
メイン ウィンドウ XAML
<Window x:Class="GridMeasureExample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GridMeasureExample"
Title="SharedSizeGroup" Height="500" Width="500">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="0"
Grid.Row="0"
Orientation="Horizontal"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Grid.IsSharedSizeScope="True">
<StackPanel Orientation="Vertical" Width="100">
<local:InfoGrid x:Name="grid1" Background="Green" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition SharedSizeGroup="Group1" />
<RowDefinition Height="15" />
</Grid.RowDefinitions>
<TextBlock Background="Blue" Grid.Row="0" Text="Row 0"/>
<TextBlock Background="Red" Grid.Row="1" Name="textBlock1" Height="100"
Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
<TextBlock Background="Blue" Grid.Row="2" Text="Row 2" />
</local:InfoGrid>
<TextBlock Text="{Binding Path=ActualHeight, ElementName=grid1}" />
</StackPanel>
<StackPanel Orientation="Vertical" Width="100">
<local:InfoGrid x:Name="grid2" Background="Yellow" ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="15" />
<RowDefinition SharedSizeGroup="Group1" />
<RowDefinition Height="15" />
</Grid.RowDefinitions>
<TextBlock Background="Orange" Grid.Row="0" Text="Row 0" />
<TextBlock Background="Purple" Grid.Row="1" Name="textBlock2" Height="150"
Text="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}"/>
<TextBlock Background="Orange" Grid.Row="2" Text="Row 2" />
</local:InfoGrid>
<TextBlock Text="{Binding Path=ActualHeight, ElementName=grid2}" />
</StackPanel>
</StackPanel>
<ListBox x:Name="lstInfo"
Grid.Column="1"
Grid.Row="0"
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<UniformGrid Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="2"
Columns="2"
HorizontalAlignment="Center"
Margin="5">
<Button x:Name="btnIncrease" Margin="4,0">Increase</Button>
<Button x:Name="btnDecrease" Margin="4,0">Decrease</Button>
</UniformGrid>
</Grid>
</Window>
メイン ウィンドウ コンストラクター (コード ビハインドのコードのみ)
public Window1() { InitializeComponent();
btnIncrease.Click += (s, e) =>
{
lstInfo.Items.Add(String.Format("{0} Increase Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff")));
textBlock2.Height += 30;
};
btnDecrease.Click += (s, e) =>
{
lstInfo.Items.Add(String.Format("{0} Decrease Button Pressed", DateTime.Now.ToString("HH:mm:ss.ffff")));
if (textBlock2.ActualHeight >= 30)
textBlock2.Height -= 30;
};
grid1.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Left Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message));
grid2.ReportInfo += (s, e) => lstInfo.Items.Add(String.Format("{0} Right Grid: {1}", e.TimeStamp.ToString("HH:mm:ss.ffff"), e.Message));
}