К сожалению, подход IValueConverter не всегда будет работать; например, если дочерние элементы добавляются в StackPanel статически, дочерняя коллекция будет пустой во время привязки (так я обнаружил). Самое простое решение - создать собственную панель:
public class ConstrainedStackPanel : StackPanel
{
public ConstrainedStackPanel()
{
}
protected override Size MeasureOverride(Size constraint)
{
foreach (var item in this.Children)
{
// FrameworkElement has the Width property we care about.
FrameworkElement element = item as FrameworkElement;
if (element != null)
constraint.Width = Math.Min(element.Width, constraint.Width);
}
return base.MeasureOverride(constraint);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
foreach (var item in this.Children)
{
// FrameworkElement has the Width property we care about.
FrameworkElement element = item as FrameworkElement;
if (element != null)
arrangeSize.Width = Math.Min(element.Width, arrangeSize.Width);
}
return base.ArrangeOverride(arrangeSize);
}
}
Вы можете использовать панель, как показано на следующем XAML:
<StackPanel Margin="5">
<TextBlock Text="StackPanel:" FontWeight="Bold" />
<StackPanel x:Name="panelA">
<Button Width="100" Content="100" />
<Button Width="200" Content="200" />
<Button Width="300" Content="300" />
<Button Width="400" Content="400" />
</StackPanel>
<TextBlock Text="ConstrainedStackPanel:" FontWeight="Bold" Margin="0,10,0,0" />
<l:ConstrainedStackPanel x:Name="panelB">
<Button Width="100" Content="100" />
<Button Width="200" Content="200" />
<Button Width="300" Content="300" />
<Button Width="400" Content="400" />
</l:ConstrainedStackPanel>
</StackPanel>
Что будет отображать что-то вроде следующего:
Надеюсь, это поможет.