John Källén
John Källén

Reputation: 7973

How to create Avalonia controls that "float" aligned bottom right above other controls

I'm porting the following Windows Forms view to Avalonia:

enter image description here

The Loading... (56%) is a Label control that has been added to the Form with the Anchor property set to Bottom, Right, so it will stay in the bottom right as the form is resized. Its Z-order is such that it always appears in front of the "Lorem ipsum" text box in the background. Once loading is completed the label is hidden.

How do I port this to Avalonia? I was looking at the Canvas class which allows full freedom of placement, but which puts a burden on the programmer to update the Canvas.Left etc properties accurately. Is there a simpler way to accomplish this?

Upvotes: 0

Views: 588

Answers (2)

John Källén
John Källén

Reputation: 7973

Consulting with the Avalonia dev team (and with thanks to @MikeCodesDotNET at Github.com), the following answer was provided. It works just as I wanted:

<Panel>
        <TextBox Text="{Binding Greeting}"
                   HorizontalAlignment="Stretch" 
                   VerticalAlignment="Stretch"
                   TextWrapping="Wrap"/>
        
        <TextBlock Text="Loading... (56%)" 
                   Background="Blue"
                   Foreground="White"
                   Padding="10"
                   VerticalAlignment="Bottom"
                   HorizontalAlignment="Right"/>
 </Panel>

Upvotes: 0

B0lver
B0lver

Reputation: 41

As my first thought, I would suggest creating a Grid with 2 rows and 2 columns. Then, you can place your loading text element in the 2nd row and 2nd column of a Grid. And your main text will be a grid children too, but with Grid.RowSpan and Grid.ColumnSpan params set to 2.

As for the actual markdown, it might look like this:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*">
    <ColumnDefinition Width="100">
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Width="*">
    <RowDefinition Width="20">
  </Grid.RowDefinitions>
  <TextBox Grid.ColumnSpan="2" Grid.RowSpan="2" />
  <Label Grid.Row="1" Grid.Column="1" Text="Loading (56%)" />
</Grid>

If you really want to be flexible with your loading text, you can put all this in a separate control and replace TextBox with ContentPresenter. That way, you can wrap anything with this newly created control and add a loading text (or rather any text) to it.

Hope it helps

Upvotes: 0

Related Questions