Как мога да накарам ScrollViewer да работи вътре в StackPanel?

В следния WPF XAML ScrollViewer не работи (показва лента за превъртане, но не можете да превъртате и съдържанието излиза от прозореца до дъното).

Мога да променя външния StackPanel на Grid и той ще работи.

Въпреки това, в моето приложение, от което възпроизведох следния код, трябва да имам външен StackPanel. Какво трябва да направя със StackPanel, за да накарам ScrollViewer да показва използваема лента за превъртане? напр. VerticalAlignment="Stretch" Height="Auto" не работят.

 <StackPanel>
        <ScrollViewer>
            <StackPanel>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
                <TextBlock Text="This is a test"/>
            </StackPanel>
        </ScrollViewer>
 </StackPanel>

person Edward Tanguay    schedule 29.04.2009    source източник


Отговори (7)


Не можете без да фиксирате височината на StackPanel. Проектиран е да расте неограничено в една посока. Бих посъветвал да използвате различен Panel. Защо "трябва" да имате външен StackPanel?

person Kent Boogaart    schedule 29.04.2009
comment
исках да подреждам нещата и използвайки мрежата, трябва ръчно да управлявате всички редове и колони, но DockPanel работи добре, така че ще премина към това, благодаря. - person Edward Tanguay; 29.04.2009
comment
Съгласен съм с Едуард. Според моя опит, опаковането на моите DataGrids в DockPanel и след това настройването на DockPanel.Dock=Top за всеки DataGrid работи страхотно. - person BitsAndBytes; 07.09.2015
comment
Коя алтернативна контрола трябва да използвам в UWP? Няма DockPanel. Благодаря ти. - person Jan Chalupa; 05.03.2016
comment
За UWP можете да използвате RelativePanel - person xmashallax; 04.04.2016
comment
По дяволите stackpanel, винаги трябва да го заменям с решетка на UWP, те трябва да променят поведението му, това е единственият панел, който работи по този начин - person Alberto Rivelli; 23.04.2016
comment
фиксирането на височината на панела на вътрешния стек ще го направи, защото тогава scrollviewer ще вземе височината му от неговия дъщерен елемент, но в случай, че височината на панела на вътрешния стек ще нарасне, същото ще се случи и с scrollviewer. Накратко, докато височината на ScrollViewer стане NaN, той ще приема размер според съдържанието си. От друга страна, ако височината на ScrollViewer е зададена, тогава той няма да се разшири, ако има съдържание. Така че най-вероятно това е по-добрият вариант. - person Kylo Ren; 06.06.2016

Това също ме притесняваше за известно време, номерът е да поставите стека си в scrollviewer.

Освен това трябва да сте сигурни, че сте задали свойството CanContentScroll на инструмента за преглед на превъртане на True, ето пример:

  <ScrollViewer Grid.Row="1" Margin="299,12,34,54" Name="ScrollViewer1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="195" CanContentScroll="True">
        <StackPanel Name="StackPanel1" OverridesDefaultStyle="False"  Height="193" Width="376" VerticalAlignment="Top" HorizontalAlignment="Left"></StackPanel>
  </ScrollViewer>
person Rob    schedule 08.07.2010
comment
Къде е свойството CanContentScroll? Вижте msdn.microsoft. com/en-us/library/ - person gideon; 24.11.2010
comment
Giddy› Моля, вижте тази връзка:- msdn.microsoft.com/en-us/ библиотека/ms612683.aspx - person Kushal Waikar; 26.11.2010
comment
Трябва да сте сигурни, че сте задали свойството CanContentScroll на инструмента за преглед на превъртане на True --- Все още не мога да повярвам, че това не е по подразбиране за контрола с име ScrollViewer. - person Andrea Antonangeli; 29.08.2017
comment
@AndreaAntonangeli Не мисля, че 'CanContentScroll' означава това, което мислите, че означава. Когато „истинското“ превъртане се извършва за елемент (или част от съдържанието), когато „фалшивото“ превъртане все още се появява, но на ниво пиксел - person mcalex; 06.03.2019

Забележете, че понякога може да имате StackPanel, без да го осъзнавате. В моя случай имах този код

<ScrollViewer>
  <ItemsControl ItemsSource="{Binding Pages}"/>
</ScrollViewer>

което работи добре. „Страниците“, посочени от обвързването, бяха наистина различни, сложни потребителски контроли и исках да имам само ленти за превъртане на някои от тях. Така че премахнах scrollviewer:

 <ItemsControl ItemsSource="{Binding Pages}"/>

И след това сложих ScrollViewer като най-горния елемент на тези от потребителските контроли, където ги исках. Това обаче не проработи. Съдържанието просто изтече от страницата. Първоначално не мислех, че този въпрос/отговор може да ми помогне, но разбрах, че панелът на елементите по подразбиране на контрола на елементи е StackPanel. Така че реших проблема си, като посочих ItemsPanel, който не беше StackPanel:

<ItemsControl ItemsSource="{Binding Pages}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
person T.J.Kjaer    schedule 16.09.2011

Ето как работи:

<Window x:Class="TabControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="clr-namespace:TabControl"
    Title="MainWindow"    Height="300"   
    DataContext="{Binding RelativeSource={RelativeSource Self}}"         
    >    
<StackPanel>
    <ScrollViewer Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}" >
        <StackPanel >
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
            <TextBlock Text="This is a test"/>                <TextBlock Text="This is a test"/>
        </StackPanel>
    </ScrollViewer>
</StackPanel>

By binding the ScrollViewer's Height to Window's Inner Height.

Логиката на преоразмеряването е, че трябва да дадем на всеки елемент фиксирана височина или да проектираме изгледа да използва височина на рендиране.

Изход:

„Лента

person Kylo Ren    schedule 09.02.2016
comment
Донякъде е близо, но не съвсем. Някой контрол, който е предшественик на ScrollViewer, но е между Border и ScrollViewer, може да има марж (моят има) и обвързването към стойността ActualHeight няма да улови това. - person Alan McBee; 04.06.2016
comment
@AlanMcBee да, може да има много възможни случаи, в които няма да работи перфектно, но това е най-основният случай за контролна йерархия, която съм дал решението. Но като се има предвид логиката, всичко, което трябва да направите в повечето случаи, е да промените типа предшественик във вашето обвързване и то трябва да работи перфектно отново. Същността на поправката беше, че в йерархията имаше елемент на потребителския интерфейс, който можеше да ни помогне да зависим от височина (не непременно граница), логиката може да остане същата, стига да намерите надеждна височина. Надявам се, че има смисъл, иначе публикувайте проблема си като въпрос, ще се опитам да помогна. :) - person Kylo Ren; 04.06.2016
comment
x:Type не е намерен. - person Bigeyes; 16.12.2016
comment
@Bigeyes коя .net версия и VS версия използвате? - person Kylo Ren; 19.12.2016
comment
@KyloRen. Visual Studio 2010 и .Net 4.0. - person Bigeyes; 19.12.2016
comment
@Bigeyes x: Типът е естествен синтаксис на WPF, трябва да има проблем с вашия дизайнер или компилатор .. - person Kylo Ren; 22.12.2016
comment
@KyloRen. Ти си прав. Опитах се да го използвам в проекта Silverlight с дъщерен прозорец на telerik. Но досега нямам представа. :-) - person Bigeyes; 22.12.2016

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

        <Grid Style="{StaticResource LayoutRootStyle}">
    <Grid.RowDefinitions>
        <RowDefinition Height="160"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>        

    <!-- Vertical scrolling grid used in most view states -->    

        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto">
            <StackPanel Orientation="Horizontal">
                <GridView>
                ...
                </GridView>
            </StackPanel>
        </ScrollViewer>        
person Luis Delgado    schedule 13.01.2013

Ето как бих го направил, ако вашият стеков панел е вътре в мрежа:

<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
    <StackPanel MaxHeight="{Binding Path=Height,RelativeSource={RelativeSource 
              AncestorType=Grid}}">
    </StackPanel>
</ScrollViewer>
person Dominic Picard    schedule 22.01.2019

Преместването на Grid.Row="1" от StackPanel към ScrollViewer го реши напълно за мен.

Имах дълъг списък от около 40 елемента за показване в StackPanel, но само първите 20 се показваха.

    <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
        <StackPanel x:Name="ContentPanel" Margin="12,0,12,0">
        <TextBlock Text="{Binding Line1}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        <TextBlock Text="" Margin="10,-2,10,0" Style="{StaticResource PhoneTextNormalStyle}" />
        ...
        </StackPanel>
    </ScrollViewer>
person user3522840    schedule 11.04.2014