wpfbindingactualwidth

wpf - Binding issue ActualWidth


I have the following XAML code:

<Grid Grid.Row="2" Name="grid_StatusBar">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="{Binding ElementName=wrapPanel, Path=ActualWidth}" />
        <ColumnDefinition Width="30" />
    </Grid.ColumnDefinitions>
    <ProgressBar Grid.Column="0" HorizontalAlignment="Stretch" Margin="5,5,5,5" Name="progressBar1" VerticalAlignment="Stretch" />
    <WrapPanel Grid.Column="1" Name="wrapPanel" HorizontalAlignment="Right">
        <Label Content="1" Height="28" HorizontalAlignment="Right" Margin="0,0,0,0" Name="label_Dataset" VerticalAlignment="Stretch" Visibility="Collapsed" />
        <Label Content="/20" Height="28" HorizontalAlignment="Right" Margin="0,0,0,0" Name="label_TotalDatasets" VerticalAlignment="Stretch" Visibility="Collapsed" />
        <Label Content="ID:" Height="28" HorizontalAlignment="Right" Margin="0,0,0,0" Name="label_IDText" VerticalAlignment="Stretch" />
        <Label Content="no id" Height="28" HorizontalAlignment="Right" Margin="0,0,0,0" Name="labelID" VerticalAlignment="Stretch" />
    </WrapPanel>
    <Button Grid.Column="2" Name="button_Help" Height="30" Width="30" Content="?" HorizontalAlignment="Right" VerticalAlignment="Stretch" Click="button_Help_Click" >
</Grid>

What i am trying to show the progressbar as wide as possible while changing the visibility of some of the labels and setting different texts (and therefore different lengths/widths.

I have then different functions:

Could anyone please help me? I do not understand why the width is not updated...

NOTE: The visibility is changed using two buttons in the window running the following code:

label_Dataset.Visibility = System.Windows.Visibility.Visible;
label_TotalDatasets.Visibility = System.Windows.Visibility.Visible;

EDIT: My target is to show the Visible Labels using the minimum space (in one line) in order to have the ProgressBar using the maximum width possible.


Solution

  • It is not possible to change the width of a parent element based on the width of a child. In your case, the column is the parent of the WrapPanel, so the ActualWidth of the WrapPanel is not available until after the grid/column has already been sized.

    Even if you wrote code to try and circumvent this, you would still run into an issue, as the measure/layout sequence would become re-entrant. Whenever the size of the column changed, it would re-layout all the child controls, one of which is the WrapPanel. This would cause the ActualWidth of the WrapPanel to be changed -- effectively causing an infinite loop. To prevent this stack overflow scenario, the framework immediately detects any re-entrancy in the layout/measure cycle and throws an exception.

    I'm not exactly sure what you are trying to achieve. Why do would you want the Labels in a WrapPanel? Surely you would always want the 4 labels to be on the same line, or at least on two lines.

    If this is the case, I would set the width of the second Column to "Auto" and put the labels in another container, i.e. one of the following: