nikobarli
Topic Author
Posts: 180
Joined: 26 Apr 2017, 06:23

ListView sample (C++ SDK, 2.0.1f1)

18 May 2017, 09:55

Hi,

Is there any sample showing how to use ListView using C++ SDK ?

Trying with the following codes but it doesn't work. Only blank control is shown:
        <ListView Margin="100,100,100,100" Grid.Column="0"  Name="ListView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100"></ColumnDefinition>
                            <ColumnDefinition Width="200"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding First}" FontWeight="Bold" />
                        <TextBlock Grid.Column="1" Text="{Binding Last}" FontWeight="Bold" />
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
NS_DECLARE_SYMBOL(First);
NS_DECLARE_SYMBOL(Last);

class DataModel : public INotifyPropertyChanged, public BaseComponent
{
public:
    NS_IMPLEMENT_INTERFACE_FIXUP

public:
    const NsChar* GetFirst() const
    {
        return _first.c_str();
    }

    void SetFirst(const NsChar* first)
    {
        if (_first != first)
        {
            _first = first;
            _propertyChanged(this, NSS(First));
        }
    }

    const NsChar* GetLast() const
    {
        return _last.c_str();
    }

    void SetLast(const NsChar* last)
    {
        if (_last != last)
        {
            _last = last;
            _propertyChanged(this, NSS(Last));
        }
    }

    PropertyChangedEventHandler& PropertyChanged()
    {
        return _propertyChanged;
    }

    // void Serialize(Noesis::Core::SerializationData* data) const
    // {
    //     data->Serialize("First", _first);
    //     data->Serialize("Last", _last);
    // }
    // 
    // void Unserialize(Noesis::Core::UnserializationData* data, NsUInt32 version)
    // {
    //     data->Unserialize("First", _first);
    //     data->Unserialize("Last", _last);
    // }

private:
    NsString _first = "First";
    NsString _last = "Last";

    PropertyChangedEventHandler _propertyChanged;

    NS_IMPLEMENT_INLINE_REFLECTION(DataModel, BaseComponent)
    {
        NsMeta<TypeId>("DataModel");
        NsImpl<INotifyPropertyChanged>();
        NsProp("First", &DataModel::GetFirst, &DataModel::SetFirst);
        NsProp("Last", &DataModel::GetLast, &DataModel::SetLast);

    }

};

////////////////////////////////////////////////////////////////////////////////////////////////////

extern "C" NS_DLL_EXPORT
void NsRegisterReflection(ComponentFactory* factory, NsBool registerComponents)
{
    NS_REGISTER_COMPONENT(DataModel);
}

        static std::vector<DataModel> g_data(10);
        auto listView(root->FindName<ListView>("ListView"));
        listView->SetItemsSource(&g_data[0]);
I also wonder how the ListView::SetItemsSource can now the length of BaseComponent array past to it ? Did I miss something ?
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ListView sample (C++ SDK, 2.0.1f1)

18 May 2017, 19:39

Hi,

In a ListView you have to set the View property (only GridView is implemented right now) to define the columns and what data is bound to each column.
You can take a look at this sample to see how it's done: http://www.wpf-tutorial.com/listview-co ... -gridview/

Following your data it would look like this:
<ListView x:Name="ListView" Margin="100">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="First" Width="100" DisplayMemberBinding="{Binding First}" />
            <GridViewColumn Header="Last" Width="200" DisplayMemberBinding="{Binding Last}" />
        </GridView>
    </ListView.View>
</ListView>
I also wonder how the ListView::SetItemsSource can now the length of BaseComponent array past to it ? Did I miss something ?
ItemsSource property expects an instance of:
  • CollectionView
  • CollectionViewSource
  • IList
You cannot use a simple pointer to a BaseComponent array. So you need to change your code to something like this:
Ptr<Collection> collection = *new Collection();
Ptr<DataModel> item = *new DataModel(); ...
collection->Add(item.GetPtr());
item = *new DataModel(); ...
collection->Add(item.GetPtr());
...
listView->SetItemsSource(collection.GetPtr());
NOTE: In NoesisGUI when declaring a component class in C++ the base implementation class must be the first one in the inheritance list, and interfaces should come next, otherwise our type system won't work and might crash.
class DataModel : public BaseComponent, public INotifyPropertyChanged
{
public:
    NS_IMPLEMENT_INTERFACE_FIXUP
    ...
};
 
nikobarli
Topic Author
Posts: 180
Joined: 26 Apr 2017, 06:23

Re: ListView sample (C++ SDK, 2.0.1f1)

19 May 2017, 03:00

Thanks. Now I understand and can make it works.
NOTE: In NoesisGUI when declaring a component class in C++ the base implementation class must be the first one in the inheritance list, and interfaces should come next, otherwise our type system won't work and might crash.
So I think this is the cause of the problem I mentioned in:
viewtopic.php?f=3&t=1077

BTW, if I have to handle a large number of items inside ListView (~100k), is there anything I can do to boost the performance ? Scrolling using the mouse wheel seems pretty fast, but dragging using scroll bar seems a bit sluggish (fps is down to 5~10 fps in my environment).

Note: During rendering, most time (100 ms~) is spent calling IView::Update(NsFloat64 timeInSeconds) . Also, a very large amount of memory is consumed when using NoesisStyle.xaml (with 100k-entry ListView, it used 600MB of memory). With WindowsStyle.xaml, it uses only several tens of MB.

Looking at the comment here: viewtopic.php?f=3&t=1089 you already have enable virtualization by default for ListView and ListBox. Is there anything else ?
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ListView sample (C++ SDK, 2.0.1f1)

22 May 2017, 18:48

Thanks. Now I understand and can make it works.

So I think this is the cause of the problem I mentioned in:
viewtopic.php?f=3&t=1077
Yes, defining a wrong class hierarchy could explain these kind of crashes.
BTW, if I have to handle a large number of items inside ListView (~100k), is there anything I can do to boost the performance ? Scrolling using the mouse wheel seems pretty fast, but dragging using scroll bar seems a bit sluggish (fps is down to 5~10 fps in my environment).
You can set ScrollViewer.IsDeferredScrollingEnabled="True" in the ListView to boost drag performance if you have problems. But we should take a look ourselves to see if we are doing something wrong, because the performance shouldn't be so bad anyway.
Note: During rendering, most time (100 ms~) is spent calling IView::Update(NsFloat64 timeInSeconds) . Also, a very large amount of memory is consumed when using NoesisStyle.xaml (with 100k-entry ListView, it used 600MB of memory). With WindowsStyle.xaml, it uses only several tens of MB.
We will do some tests to verify if we are doing anything wrong, because the memory difference is huge.
Looking at the comment here: viewtopic.php?f=3&t=1089 you already have enable virtualization by default for ListView and ListBox. Is there anything else ?
Apart from what is explained in that post, you don't have to do anything.
If virtualization is not enabled, then most of the time is spent during first loading of the ListView, but then it should scroll smoothly.
If virtualization is enabled, then loading will be almost instant, but you might experience a bit of lag when scrolling if items are too complex to generate.
 
nikobarli
Topic Author
Posts: 180
Joined: 26 Apr 2017, 06:23

Re: ListView sample (C++ SDK, 2.0.1f1)

23 May 2017, 09:09

BTW, if I have to handle a large number of items inside ListView (~100k), is there anything I can do to boost the performance ? Scrolling using the mouse wheel seems pretty fast, but dragging using scroll bar seems a bit sluggish (fps is down to 5~10 fps in my environment).
You can set ScrollViewer.IsDeferredScrollingEnabled="True" in the ListView to boost drag performance if you have problems. But we should take a look ourselves to see if we are doing something wrong, because the performance shouldn't be so bad anyway.
Note: During rendering, most time (100 ms~) is spent calling IView::Update(NsFloat64 timeInSeconds) . Also, a very large amount of memory is consumed when using NoesisStyle.xaml (with 100k-entry ListView, it used 600MB of memory). With WindowsStyle.xaml, it uses only several tens of MB.
We will do some tests to verify if we are doing anything wrong, because the memory difference is huge.
Great. Please post the result once you have finished the investigation. Currently we are evaluating a use case that requires showing ~100k-entry of data grid.
 
nikobarli
Topic Author
Posts: 180
Joined: 26 Apr 2017, 06:23

Re: ListView sample (C++ SDK, 2.0.1f1)

30 May 2017, 02:16

Hi,

I filed a bug here regarding the memory usage when using NoesisStyle.xaml: https://bugs.noesisengine.com/view.php?id=1099

Please take a look.

Thanks.
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ListView sample (C++ SDK, 2.0.1f1)

30 May 2017, 15:52

Hi,

I've been investigateing and I found the source of the memory problems. The ListView default style defined in NoesisStyle.xaml was not allowing the virtualization to take place, so it was generating all the 10K items added to the list.

You just need to modify line 6005 to:
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
We will include this change in the next release.
 
nikobarli
Topic Author
Posts: 180
Joined: 26 Apr 2017, 06:23

Re: ListView sample (C++ SDK, 2.0.1f1)

31 May 2017, 01:19

Great. Thank you.
 
User avatar
jsantos
Site Admin
Posts: 3939
Joined: 20 Jan 2012, 17:18
Contact:

Re: ListView sample (C++ SDK, 2.0.1f1)

02 Jun 2017, 01:44

Marking this as solved

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 12 guests