Search code examples
c#xamlbindinguwpwindows-community-toolkit

uwp adaptiveGridView throws exception on OneRowMode


I am having following exception on my adaptivegridview of uwp community toolkit

"System.ArgumentException: Value does not fall within the expected range. \r\n at Windows.UI.Xaml.FrameworkElement.SetBinding(DependencyProperty dp, BindingBase binding)\r\n at Microsoft.Toolkit.Uwp.UI.Controls.AdaptiveGridView.DetermineOneRowMode()\r\n at Microsoft.Toolkit.Uwp.UI.Controls.AdaptiveGridView.OnLoaded(Object sender, RoutedEventArgs e)"

XAML

<controls:AdaptiveGridView Name="AllVideosGridView" 
                                           OneRowModeEnabled="True"
                                           MaxHeight="260"
                                           ScrollViewer.HorizontalScrollMode="Enabled"
                                           ScrollViewer.HorizontalScrollBarVisibility="Auto"
                                           ItemClick="AllVideosGridView_ItemClick"
                                           Style="{StaticResource MainGridView}"
    <...data template and other stuff...>
</controls.........>

the error occurs due to property OneRowModeEnabled to True, and if I remove that property it works fine and after app runs and then I set this property to true, while app is running then it doesn't show any exception and gridview goes to one row mode as it should.

Also the code behind doesn't matter, because I tried to commend the code behind which initializes the itemsource, but this exception still occurs.


Solution

  • The problem here is that you didn't set ItemHeight property in AdaptiveGridView.

    Form the source code of AdaptiveGridView, you can find the following code (L155-L186):

    private void OnLoaded(object sender, RoutedEventArgs e)
    {
        _isLoaded = true;
        DetermineOneRowMode();
    }
    
    private void DetermineOneRowMode()
    {
        if (_isLoaded)
        {
            var itemsWrapGridPanel = ItemsPanelRoot as ItemsWrapGrid;
    
            if (OneRowModeEnabled)
            {
                var b = new Binding()
                {
                    Source = this,
                    Path = new PropertyPath("ItemHeight")
                };
    
                if (itemsWrapGridPanel != null)
                {
                    _savedOrientation = itemsWrapGridPanel.Orientation;
                    itemsWrapGridPanel.Orientation = Orientation.Vertical;
                }
    
                SetBinding(MaxHeightProperty, b);
                ...
    

    When OneRowModeEnabled set to True, it will bind MaxHeightProperty to ItemHeight property. However, as you didn't set a value to ItemHeight property, its value will be NaN. That's why you got Value does not fall within the expected range. error.

    To solve this problem, you can set ItemHeight property like the following:

     <controls:AdaptiveGridView Name="AllVideosGridView"
                                       OneRowModeEnabled="True"
                                       DesiredWidth="260"
                                       ItemHeight="200"
                                       SelectionMode="None"
                                       StretchContentForSingleRow="False"
                                       IsItemClickEnabled="True"
                                       ItemsSource="{x:Bind ViewModel.Videos, Mode=OneWay}">
        ...
    </controls:AdaptiveGridView>