views:

89

answers:

2

Hi, I have a grid where one columnwidth is defined as *. The other columns are defined as Auto. The column with the *-definition contains a usercontrol derived from Panel that also implements IScrollInfo. During this control's MeasureOverride visibility is set to visible on a RepeatButton in another column (the RepeatButton's visibility is otherwise set to collapsed).

This does not cause the column to expand. This will only occur when I resize my window. A simplified example:

<DockPanel LastChildFill="True">
    <Grid DockPanel.Dock="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="TabItemColumn"/>
            <ColumnDefinition x:Name="ScrollRightColumn" Width="Auto"/>
        </Grid.ColumnDefinitions>
        <ScrollViewer x:Name="PART_ScrollViewer" 
                Grid.Column="0" 
                Margin="-1,0,0,0" 
                Height="32" 
                CanContentScroll="True" 
                VerticalScrollBarVisibility="Hidden" 
                HorizontalScrollBarVisibility="Hidden" 
                HorizontalAlignment="Left">
            <local:TabPanel 
                    x:Name="tabPanel" 
                    HorizontalAlignment="Left" 
                    IsItemsHost="True" />
        </ScrollViewer>

        <RepeatButton Style="{StaticResource RepeatButtonScrollRight}"
            Visibility="{Binding ElementName=tabPanel, Path=CanScrollRight, Converter={StaticResource _localBooleanConverter}}"
            Grid.Column="1">
        </RepeatButton>

The visibility of the RepeatButton is triggered correctly, and as far as I can tell it is actually rendered, but the ActualWidth of the containing column is zero until resize.

Any ideas?

A: 

You'll need to trigger a layout change after changing the column width. Use InvalidateArrange() on the proper parent element. Take care to avoid infinite cycles.

David Schmitt
I suspected as much, but I feel I have tried invalidating on all possible elements without much luck.To clarify: I never set the width. The width of the column is set to Auto, and should expand to a size when the repeatbuttons visibility is set to visible.I assume the parent element is the grid. Calling InvalidateArrange() on the Grid, in the CanScrollRight property setter has no effect.
risingape
Its hard to say where exactly the problem lays in your example code but it looks like it should work. I can see one possible place where it could have this effect is that you do not have any content in your RepeatButton. Generally text should be here otherwise the button will be "Auto" to 0 width. Good luck.
Tri Q
@risingape: Tri Q is correct about the default button width in general, however in your case it may not apply: As long as your RepeatButtonScrollRight ControlTemplate always has a non-zero width, it doesn't matter whether there is Content or not.
Ray Burns
A: 

InvalidateArrange is a good answer, but unfortunately it is silently ignored during the time a control is actually being arranged. So the trick is to call it after the arrange is complete.

This may work (I haven't tried it):

Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
  grid.InvalidateArrange();
}));

If this doesn't work, you might try calling InvalidateArrange and/or InvalidateMeasure on the RepeatButton, also within a Dispatcher.BeginInvoke callback.

Ray Burns