Reputation: 100
Working with UWP means I cant use DIP values always. I rely on "auto" sizes, "Stretch" alignments, etc. I narrowed my problem to this:
How Can I Bind Height and Width of Element to Another Element, which has Height and Width "Auto"?
Sample:
<Grid.RowDefinitions>
<RowDefinition x:Name="CardGriddRow1" Height="2*" />
<RowDefinition x:Name="CardGrdidRow2" Height="1*" />
</Grid.RowDefinitions>
<Rectangle Name="Rec1" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Width="auto" Height="auto" Grid.Row="1" Margin="20" />
<Rectangle Name="Rec2" Fill="Yellow" Grid.Row="0" Height="{x:Bind Rec1.ActualHeight, Mode=OneWay }" Width="{x:Bind Rec1.ActualWidth, Mode=OneWay }" HorizontalAlignment="Left" VerticalAlignment="Top" />
When using ActualHeight, I can use only OneWay mode. Height value is NaN. Rec2 will have 0 values but ActualHeight of Rec1 is more than 0.
Is there way to force Binding to take ActualHeight?
Upvotes: 0
Views: 1210
Reputation: 531
I would try to avoid the SizeChanged
event as much as possible as it fires so often when the screen is resized it can cause the UI to start freezing and drop in frame rate. Let the Xaml do as much of the work as possible. I've recreated the scenario you've shown in the link you attached in your comment using Xaml only. See screenshot:
It may not be exactly the same as yours but with some styling it could be.
See code:
<Page>
<Page.Resources>
<Style TargetType="Rectangle">
<Setter Property="VerticalAlignment"
Value="Stretch"/>
<Setter Property="HorizontalAlignment"
Value="Stretch" />
</Style>
</Page.Resources>
<Grid Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="8">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Row="0"
Grid.Column="1"
Fill="Red" />
<Rectangle Grid.Row="0"
Grid.Column="2"
Fill="Yellow" />
</Grid>
<Rectangle Grid.Row="2"
Grid.Column="0"
Fill="Blue" />
<Rectangle Grid.Row="2"
Grid.Column="1"
Fill="Red" />
<Rectangle Grid.Row="2"
Grid.Column="2"
Fill="Green" />
<Rectangle Grid.Row="2"
Grid.Column="3"
Fill="Yellow" />
<Rectangle Grid.Row="2"
Grid.Column="4"
Fill="Brown" />
<Rectangle Grid.Row="2"
Grid.Column="5"
Fill="Pink" />
<Rectangle Grid.Row="2"
Grid.Column="6"
Fill="Purple" />
<Rectangle Grid.Row="2"
Grid.Column="7"
Fill="Orange" />
</Grid>
</Page>
Upvotes: 0
Reputation: 10627
How Can I Bind Height and Width of Element to Another Element, which has Height and Width "Auto"?
ActualHeight
is a calculated property. For purposes of ElementName
binding, ActualHeight
does not post updates when it changes (due to its asynchronous and run-time calculated nature). Do not attempt to use ActualHeight
as a binding source for an ElementName
binding. If you have a scenario that requires updates based on ActualHeight
, use a SizeChanged
handler. Details please reference ActualHeight
property.
Although updated your code snippet to use binding instead as follows, it seems like worked , but it is not reliable that you should not use it .
<Rectangle Name="Rec1" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1" Margin="20" Height="auto" Width="auto" />
<Rectangle Name="Rec2" Height="{Binding Path=ActualHeight,ElementName=Rec1}" Width="{Binding Path=ActualWidth,ElementName=Rec1}" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="Yellow" Grid.Row="0"/>
The correct way as the document mentioned, you could use SizeChanged
, for example:
<Rectangle Name="Rec1" SizeChanged="Rec1_SizeChanged" Fill="Blue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Row="1" Margin="20" Height="auto" Width="auto" />
<Rectangle Name="Rec2" Fill="Yellow" Grid.Row="0" HorizontalAlignment="Left" VerticalAlignment="Top" />
Code behind:
private void Rec1_SizeChanged(object sender, SizeChangedEventArgs e)
{
Rec2.Height = Rec1.ActualHeight;
Rec2.Width = Rec1.ActualWidth;
}
Upvotes: 1