View Issue Details

IDProjectCategoryView StatusLast Update
0001809NoesisGUIC++ SDKpublic2020-10-19 10:53
ReporterstevehAssigned Tosfernandez 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version3.0.6 
Target Version3.0.7Fixed in Version3.0.7 
Summary0001809: Selector doesn't synchonise selected index correctly
DescriptionHI guys,

I've recently updated to 3.0.6 from 3.0.0 and I'm experiencing a new issue. I have a listbox with ItemsSource bound to an ObservableCollection in code. The XAML binds the SelectedValue to an entry which is set up in the constructor of the data context.

class MyLeafObject{}

class MyStruct
{
public:
    ObservableCollection<MyLeafObject> LeafObjects;
    MyLeafObject SelectedLeaf;
}

class MyDataContext
{
    MyDataContext()
    {
        Entries = MakePtr<ObservableCollection<MyStruct>>();
        Entries->Add(MakePtr<MyStruct>());
        // ...
        CurrentStruct = Entries->Get(0); // Set default selected value
    }
private:
    ObservableCollection<MyStruct> Entries;
    MyStruct CurrentStruct;
}

<ListBox x:Name="MyParentLB" ItemsSource="{Binding Entries}" SelectedValue="{Binding Path=CurrentStruct, Mode=TwoWay}" />
<ListBox x:Name="MyLeafLB" ItemsSource="{Binding CurrentStruct.LeafObjects}" SelectedValue="{Binding Path=CurrentStruct.CurrentLeaf, Mode=TwoWay}" />




This all worked in 3.0.0. When the item container generator generated the listboxitems, it correctly applied the selected state to the entry we set in MyDataContext::MyDataContext.

Since updating to 3.0.6, this no longer happens. From what I can see, the Selector::SelectedIndex / Selector::SelectedValue are correct, but the Selector::mSelectedIndices array never gets populated. I've trace it through the following callstack:

> game.exe!Noesis::Selector::SynchronizeWithCurrent(int currentIndex) Line 774 C++
     game.exe!Noesis::Selector::OnItemsSourceChanged(Noesis::BaseComponent * __formal, Noesis::BaseComponent * __formal) Line 153 C++
     game.exe!Noesis::ItemsControl::OnPropertyChanged(const Noesis::DependencyPropertyChangedEventArgs & args) Line 700 C++
     game.exe!Noesis::Selector::OnPropertyChanged(const Noesis::DependencyPropertyChangedEventArgs & args) Line 584 C++

if (!sync.HasValue())
    {
        // Sync if ItemsSource is a CollectionView
        CollectionView* cv = DynamicCast<CollectionView*>(GetItemsSource());
        if (cv != 0)
        {
            if (GetSelectedIndex() != currentIndex)
            {
                SetSelectedIndex(currentIndex);
            }
            else
            {
                GetItems()->MoveCurrentToPosition(currentIndex);
            }
        }
    }


The ItemsSource is not a CollectionView object, so "if (cv != 0)" does not succeed. So the ItemsSource all looks good, the dependency property code is all bound / initialise correctly, but none of the properties syncrhonise the mSelectedIndices array.

So when we finally get around to generating the containers:

> game.exe!Noesis::Selector::OnContainersGenerated() Line 528 C++
     [Inline Frame] game.exe!Noesis::Delegate<void __cdecl(Noesis::BaseComponent *,Noesis::EventArgs const &)>::operator()(Noesis::BaseComponent *) Line 172 C++
     [Inline Frame] game.exe!Noesis::ItemContainerGenerator::SetStatus(Noesis::GeneratorStatus) Line 252 C++
     game.exe!Noesis::ItemContainerGenerator::Stop() Line 616 C++
     game.exe!Noesis::Panel::GenerateChildren() Line 544 C++


It bails out here:

            // Update container IsSelected as specified by selected items list
            int32_t itemIndex = generator->IndexFromContainer(container);
            bool isSelected = Finder::Find(mSelectedIndices, itemIndex);
            if (GetIsSelected(container) != isSelected)
            {
                SetIsSelected(container, isSelected);
            }


The condition fails because isSelected returns false. itemIndex is correctly set to 0, the container is set to our correct ListBoxItem, and GetIsSelected(ListBoxItem) returns false. If mSelectedIndices contained my selected index at this point everything should work fine.

Any idea how I can go about fixing this? I can manually call "->SetSelectedIndex(0)" when the containers are generated, but this just feels like a hack, the bindings should update the selected property ideally.

Sorry for the wall of text,

Cheers,

-Steven
TagsNo tags attached.
PlatformAny

Activities

sfernandez

sfernandez

2020-10-16 11:45

manager   ~0006683

Thanks a lot for the detailed report, I'm investigating this right now.
sfernandez

sfernandez

2020-10-19 10:53

manager   ~0006695

Solved in revision 9677.

Issue History

Date Modified Username Field Change
2020-10-14 21:54 steveh New Issue
2020-10-14 21:54 steveh Description Updated View Revisions
2020-10-14 21:56 jsantos Target Version => 3.0.7
2020-10-14 21:56 jsantos Assigned To => sfernandez
2020-10-14 21:56 jsantos Status new => assigned
2020-10-16 11:45 sfernandez Note Added: 0006683
2020-10-19 10:53 sfernandez Status assigned => resolved
2020-10-19 10:53 sfernandez Resolution open => fixed
2020-10-19 10:53 sfernandez Fixed in Version => 3.0.7
2020-10-19 10:53 sfernandez Note Added: 0006695