0

Is there a way to prevent a wrap panel (or other control) from participating in a scrollviewers width calculation? For example below, I'd like the wrap panel to stay within the width created by other controls but not directly affect the width calculation. (i.e.) I'd like behavior similar to if Auto was off, but still allow horizontal scrolling of other content gets wider.

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <ScrollViewer HorizontalScrollBarVisibility="Auto">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <WrapPanel Grid.Column="1" Name="ctlWrap" />
            <TextBox Grid.Row="1" Grid.Column="1" Width="100" HorizontalAlignment="Left" Name="ctlText" />
            <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
                <Button Click="Button_Click">Add Wrap</Button>
                <Button Click="Button_Click_1">Remove Wrap</Button>
                <Button Click="Button_Click_2">Add Text</Button>
                <Button Click="Button_Click_3">Remove Text</Button>
            </StackPanel>
        </Grid>
    </ScrollViewer>
</Grid>
</Window>

Here's the code I used for the buttons:

Class MainWindow 

Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
    ctlWrap.Children.Add(New Button With {.Content = "Button " & ctlWrap.Children.Count + 1})
End Sub

Private Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
    If ctlWrap.Children.Count Then
        ctlWrap.Children.RemoveAt(ctlWrap.Children.Count - 1)
    End If
End Sub

Private Sub Button_Click_2(sender As Object, e As RoutedEventArgs)
    ctlText.Width += 30
End Sub

Private Sub Button_Click_3(sender As Object, e As RoutedEventArgs)
    If ctlText.Width > 60 Then ctlText.Width -= 30
End Sub
End Class
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
  • Your question is unclear... it sounds like you might need to develop your own custom `Panel`, but I'm not exactly sure of what you want. – Sheridan Jul 31 '13 at 09:26
  • I'd like the wrap panel to size to the effective size of the scroller without affecting the scrollers width. There are two conditions: 1) all other content fits in the view space. The wrap panel should be the width of the view space. 2) Some other content is wider than the view space, the scroller allows scrolling out to that width. The wrap panel should be that new width. i.e. It sizes to the scrollers width, but doesn't affect the scrollers width. In my scenario, the wrap panel is in the second column of a grid that is in the scroller. – user2637281 Jul 31 '13 at 10:57

1 Answers1

3

I capitulated slightly. I put the buttons in the left column of the grid and then bound the width and maxwidth to the viewportwidth of the scroller and the left margin to the horizatonal offset.

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:WpfApplication14"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <app:MarginConverter x:Key="mc" />
</Window.Resources>
<Grid>
    <ScrollViewer HorizontalScrollBarVisibility="Auto" Name="ctlScroll">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100" />
                <ColumnDefinition Width="1*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <WrapPanel Grid.ColumnSpan="2" Grid.Column="0" Name="ctlWrap" Width="{Binding ViewportWidth, ElementName=ctlScroll}" MaxWidth="{Binding ViewportWidth, ElementName=ctlScroll}" Margin="{Binding HorizontalOffset, ElementName=ctlScroll, Converter={StaticResource mc}}" HorizontalAlignment="Left" />
            <TextBox Grid.Row="1" Grid.Column="1" Width="100" HorizontalAlignment="Left" Name="ctlText" />
            <StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
                <Button Click="Button_Click">Add Wrap</Button>
                <Button Click="Button_Click_1">Remove Wrap</Button>
                <Button Click="Button_Click_2">Add Text</Button>
                <Button Click="Button_Click_3">Remove Text</Button>
            </StackPanel>
        </Grid>
    </ScrollViewer>
</Grid>
</Window>

The margin converter came from here.

Community
  • 1
  • 1