I'm trying to center a modal popup-style control on a xaml screen relative to the entire screen, but also have the central control get pushed out of the way by a sibling (side panel) in the event the control is so large the two would intersect. This is feasible with codebehind, datanbindings, data triggers, custom controls and other less than totally elegant approaches, but is there a way to solve this problem out of the box with only xaml?
Here's a greatly simplified version of the problem which is a window with two rectangles. The orange rectangle is always 200px. The green rectangle is variably sized but never larger than 600px. Can we make the green rectangle center on the screen unless it is wide enough that it would collide with the orange rectangle in which case the green rectangle is laid out to the right of the orange rectangle (like a stackpanel)? The green and orange rectangles can be placed into any containers you want and the containers can be nested any way you want.
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Width="800">
<Rectangle Width="200" Fill="Orange" HorizontalAlignment="Left" ></Rectangle>
<Rectangle Width="300" Fill="Green" HorizontalAlignment="Center"></Rectangle>
</Grid>
</Window>
CodePudding user response:
There is no built-in way to do this, but this approach works and is fairly simple:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Width="200" Fill="Orange" HorizontalAlignment="Left" />
<Rectangle Grid.Column="1" Width="300" Fill="Green" HorizontalAlignment="Center"/>
</Grid>
And if you prefer not to duplicate the width of the orange rectangle you can do this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="{Binding ElementName=OrangeRectangle, Path=ActualWidth}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="OrangeRectangle" Width="200" Fill="Orange" HorizontalAlignment="Left" />
<Rectangle Grid.Column="1" Width="300" Fill="Green" HorizontalAlignment="Center"/>
</Grid>