'Specified argument was out of the range of valid values. (Parameter 'itemIndex')'

Emon Haque 3,176 Reputation points
2020-10-19T08:17:52.773+00:00

I got this error:

33332-test.gif

on the ComboBox before and at that time, it was a VirtualizingStackPanel there in the ScrollViewer. I changed it to ItemsPresenter and had no problem with this until I added ItemContainerStyle and this:

<Trigger Property="IsFocused" Value="True">  
       <Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=toggle}" TargetName="toggle"/>  
</Trigger>  

inside the ControlTemplate.Triggers of Template today! Here's the ItemContainerStyle:

<Setter Property="ItemContainerStyle">  
    <Setter.Value>  
        <Style TargetType="ComboBoxItem">  
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>  
            <Setter Property="Template">  
                <Setter.Value>  
                    <ControlTemplate TargetType="ComboBoxItem">  
                        <Border x:Name="panel">  
                            <ContentPresenter ContentSource="{TemplateBinding Content}" />  
                        </Border>  
                        <ControlTemplate.Triggers>  
                            <Trigger Property="IsSelected" Value="True">  
                                <Setter TargetName="panel" Property="Background" Value="LightSkyBlue"/>  
                                <Setter TargetName="panel" Property="TextElement.FontWeight" Value="Bold"/>  
                            </Trigger>  
                            <Trigger Property="IsFocused" Value="True">  
                                <Setter TargetName="panel" Property="Background" Value="LightGray"/>  
                                <Setter TargetName="panel" Property="TextElement.FontWeight" Value="Bold"/>  
                            </Trigger>  
                        </ControlTemplate.Triggers>  
                    </ControlTemplate>  
                </Setter.Value>  
            </Setter>  
        </Style>  
    </Setter.Value>  
</Setter>  

One more thing that might be relevant for this: this combo's been used in a custom control, ComboField, and there on onChanged callback I've these:

    public static readonly DependencyProperty SourceProperty =  
        DependencyProperty.Register("Source", typeof(IEnumerable), typeof(ComboField), new PropertyMetadata(null, onChanged));  

    static void onChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
    {  
        if (e.NewValue is ICollectionView)  
            if(e.OldValue != null)  
                (e.OldValue as ICollectionView).CollectionChanged -= onCollectionChanged;  
        (e.NewValue as ICollectionView).CollectionChanged += onCollectionChanged;  
    }  

    static void onCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)  
    {  
        var view = sender as ICollectionView;  
        switch (e.Action)  
        {  
            case NotifyCollectionChangedAction.Add:  
                if (view.CurrentItem != e.NewItems[0])  
                    view.MoveCurrentTo(e.NewItems[0]);  
                break;  

            case NotifyCollectionChangedAction.Reset:  
                if (e.NewItems == null && !view.IsEmpty)  
                    view.MoveCurrentToFirst();  
                break;  
        }  
    }  

here's the project link, the second one RentManager with ICollectionView.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,784 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Emon Haque 3,176 Reputation points
    2020-10-19T18:28:05.543+00:00

    The porblem is ItemsPanel:

    <Setter Property="ItemsPanel">  
        <Setter.Value>  
            <ItemsPanelTemplate>  
                <VirtualizingStackPanel/>  
            </ItemsPanelTemplate>  
        </Setter.Value>  
    </Setter>  
    

    if I remove this from Combo, it works with ItemsPresenter BUT if I keep it, I've to replace ItemsPresenter with someother ItemsHost! I'm not sure whether these:

    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>  
    <Setter Property="VirtualizingPanel.IsVirtualizing" Value="True"/>  
    <Setter Property="VirtualizingPanel.VirtualizationMode" Value="Recycling"/>  
    

    in Setter instead of ItemsPanel enables UI Virtualization or not.

    EDIT

    It also works with ItemsPanel and without those three top level Setter, if I Refresh the view on Add

    static void onCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)  
    {  
        var view = sender as ICollectionView;  
        switch (e.Action)  
        {  
            case NotifyCollectionChangedAction.Add:  
                if (view.CurrentItem != e.NewItems[0])  
                {  
                    view.MoveCurrentTo(e.NewItems[0]);  
                    //view.Refresh();  
                }  
                break;  
            case NotifyCollectionChangedAction.Reset:  
                if (e.NewItems == null && !view.IsEmpty)  
                    view.MoveCurrentToFirst();  
                break;  
        }  
    }  
    

    BUT why would I do that? What's the point of IsSynchronizedWithCurrentItem=true?

    I've two static ICollectionView (Plots and ControlHeads) which don't have filter/sort/grouping and are bound to several ComboField in different views. To reduce the hit in CurrentChanged handlers in different viewmodels I've added this:

    if (view.CurrentItem != e.NewItems[0])  
        view.MoveCurrentTo(e.NewItems[0]);  
    

    and as the CurrentItem is in one place, static ICollectionView, and I've IsSynchronizedWithCurrentItem=true, I neither have to move everywhere nor refresh the view right?

    EDIT

    Visually the Combo in the ComboField is in sync with CurrentItem and the SelectedItem is also in sync. With this in the overridden OnItemsChanged of Combo

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)  
    {  
        switch (e.Action)  
        {  
            case NotifyCollectionChangedAction.Add:  
                if(SelectedItem != e.NewItems[0])  
                    SelectedItem = e.NewItems[0];  
                break;  
            case NotifyCollectionChangedAction.Reset:  
                if (e.NewItems == null && !Items.IsEmpty)  
                    Items.MoveCurrentToFirst();  
                break;  
        }  
    }  
    

    I can see that in case of ICollectionView, Plots, it hits Add 6 times (there're 6 ComboField bound to static ICollectionView Plots) when I add a plot and it escapes the assignment of SelectedItem 5 times. The one that assigns the SelectedItem = e.NewItems[0], shows the popup when I click on toggle BUT the rest which escaped the assignment, throws the exception!

    To get rid of this exception I've to reassign SelectedItem = e.NewItems[0] for all by removing the if guard in Add block and ComboField's onCollectionChanged can be empty.

    So the question is why do I have to reassign?

    EDIT

    Moving the code in Combo instead of ComboField doesn't solve the problem either, for some reason it worked once/twice when I wrote! After deleting bin, obj, .vs folders, now the first Combo in Space section of UI works BUT the second in the Lease section throws that:

    33474-test.gif

    so as I move the code from ComboField.cs to Combo.cs, the exception moves.

    0 comments No comments

  2. Emon Haque 3,176 Reputation points
    2020-10-20T07:57:47.56+00:00

    Tried by retemplating the Combo BUT it still doesn't work sometimes! The interesting thing is sometimes it works without problem and sometimes throws that exception. I've added another combobox, DefaultCombo, in addition to the original Combo in the project to narrow down the problematic area and feels like it's the ToggleButton or the Path inside the toggle button.

    It could also be because of ICollectionView or IsSynchronizedWithCurrentItem. I've worked with the same Combo in two other projects BUT I didn't use ICollectionView or IsSynchronizedWithCurrentItem in those and I didn't have any issue with this.

    The project's been updated in GitHub.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.