Search code examples
c#windowsxamluwpscrollviewer

UWP independent scrollviews


The idea is to have a one column with lots of elements in a scrollable listview and a second column (not scrollable) with small details. The problem is that entire page is scrolling and as a result the second column is out of the view.

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Scrollviewer x:Name="scrollviewer" Grid.Column="0">
            <Listview ItemsSource={...} ItemTemplate={...} />
        </Scrollviewer>
        <StackPanel Grid.Column="1">
            <...>
        </StackPanel>
</Grid>

I've tried to link window height to scrollviewer height with SizeChanged event (scrollviewer.Height = Window.Current.Bounds.Height), and it works kind of until I scroll for a little bit and then it crashes with an error "Layout cycle detected". I think it supposed to be very common scenario and I am missing something here. Can anyone help?

enter image description here


Solution

  • I can’t reproduce your issue. You could check the following sample to compare your code.

    MainPage.xaml:

    <Page
    ..>
    
    <Grid>
        <NavigationView PaneDisplayMode="Left"  ItemInvoked="NavigationView_ItemInvoked">
            <NavigationView.MenuItems >
                <NavigationViewItem Content="A" x:Name="A" />
                <NavigationViewItem Content="B" x:Name="B" />
                <NavigationViewItem Content="C" x:Name="C" />
            </NavigationView.MenuItems>
            <Frame x:Name="ContentFrame"/>
        </NavigationView>
    </Grid>
    

    MainPage.xaml.cs:

    private void NavigationView_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
        {
            var item = args.InvokedItemContainer;
            switch (item.Name)
            {
                case "B":
                    ContentFrame.Navigate(typeof(BlankPage1));
                    break;
            }
        }
    

    BlankPage1.xaml:

    <Page
    ..>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
    
            <ListView x:Name="listView" ItemsSource="{x:Bind Fruits}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="local:Fruit">
                        <TextBlock Text="{x:Bind price}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
     
        <StackPanel Grid.Column="1">
            <TextBlock Text="yyyyyyyyygggg"/>
            <TextBlock Text="hkcsduhgfuhiualhfijht" />
        </StackPanel>
    </Grid>
    

    BlankPage1.xaml.cs:

    public sealed partial class BlankPage1 : Page
    {
        public ObservableCollection<Fruit> Fruits { get; set; }
        public BlankPage1()
        {
            this.InitializeComponent();
            Fruits = new ObservableCollection<Fruit>()
            {
                new Fruit(){name="apple",price=12},
                new Fruit(){name="peach",price=15},
                new Fruit(){name="pear",price=8},
                new Fruit(){name="banana",price=31},
                new Fruit(){name="grape",price=5},
                .......
                // Add items that fill the entire page
               new Fruit(){name="banana",price=31},
                new Fruit(){name="grape",price=5},
                new Fruit(){name="apple",price=12}
                       
            };
          
        }
    }
    public class Fruit
    {
        public string name { get; set; }
        public int price { get; set; }
    }