Scrollviewer в друг

Започнах да използвам WPF неотдавна и се занимавах с проблем със ScrollViewer, който всъщност изглежда доста често срещан: имам ScrollViewer с вариращо съдържание, което се показва заедно с друго съдържание, и цялото нещо е вътре в друг ScrollViewer . Цялата работа изглежда нещо подобно:

<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
    <StackPanel Orientation="Vertical">
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
            <StackPanel Orientation="Vertical">
                <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
            </StackPanel>
        </ScrollViewer>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
    </StackPanel>
</ScrollViewer>

Това, което искам, е вътрешният ScrollViewer да започне да намалява съдържанието си преди външния, което означава, че ако имам всичко това в прозорец и намаля размера на прозореца, искам ScrollViewer със син правоъгълник да започне да намалява съдържанието си и да показва своята лента за превъртане преди външната, тази, съдържаща оранжевия правоъгълник, го прави.

След като гледах в интернет дълго време, намерих два основни съвета: първият е да избягвам използването на StackPanel - в този опростен пример очевидно бих могъл да използвам Grid, на практика в реалния проект не съм сигурен, че мога, тъй като съдържанието, което поставям в този ScrollViewer, е с различен размер в зависимост от това, което обвързвам там. Второто е нещо, което намерих в отговор на зловещо подобен въпрос:

Вложени области за превъртане

Което в началото изглеждаше добре. Полученият xaml става:

<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
    <StackPanel Orientation="Vertical">
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <local:RestrictDesiredSize MinHeight="60">
            <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
                <StackPanel Orientation="Vertical">
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                </StackPanel>
            </ScrollViewer>
        </local:RestrictDesiredSize>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
    </StackPanel>
</ScrollViewer>

Но сега имам обратния проблем: вътрешният scrollviewer винаги е заседнал на височина 60, дори ако разширя прозореца, но бих искал да заеме възможно най-много място - показване на всички сини правоъгълници и скриване на плъзгача, ако възможен

Някой знае ли как да се постигне това?

РЕДАКТИРАНЕ:

Намерих временно решение, което не е перфектно, като използвам DockPanel някъде вместо StackPanel, предполагам, че наистина би било по-лесно да се реши това, като се избягват стековите панели заедно? Ето последната версия, която имам

<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch">
    <DockPanel>
        <StackPanel DockPanel.Dock="Top">
            <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
            <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        </StackPanel>
        <StackPanel DockPanel.Dock="Bottom">
            <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
            <Rectangle Height="50" Width="50" Margin="5" Fill="Orange"/>
        </StackPanel>
        <local:RestrictDesiredSize MinHeight="60">
            <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch">
                <StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                    <Rectangle Height="50" Width="50" Margin="5" Fill="Blue"/>
                </StackPanel>
            </ScrollViewer>
        </local:RestrictDesiredSize>
    </DockPanel>
</ScrollViewer>

Сега не е перфектно, защото част от съдържанието е закрепено в долната част, но ще опитам това като заобиколно решение засега, освен ако не намеря нещо по-добро.


person Brys    schedule 05.06.2015    source източник


Отговори (1)


Решавал съм този проблем в миналото чрез обвързване на подходящата ширина към родителя ActualWidth с помощта на RelativeSource.

Вижте Как да използвам WPF свързвания с RelativeSource?.

Snoop също е много полезен, за да разберете как да намерите желаното от вас свойство във Visual Tree, вижте моя урок за Snoop на Грешка на ReSharper WPF: Не може да се разреши символ MyVariable поради неизвестен DataContext.

person Contango    schedule 06.06.2015
comment
Бихте ли разяснили повече? Прекарах известно време в обвързване на произволни височини, но не мога да намеря правилната. - person Brys; 08.06.2015
comment
Добавени още няколко съвета. - person Contango; 08.06.2015