ListView1->Items->Item[i]->Height = 0???

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

ListView1->Items->Item[i]->Height = 0???

Postby Lena » Fri Oct 27, 2017 8:23 am

Code: Select all
void __fastcall TForm1::ListBoxItem1Click(TObject *Sender)
{
 try
  {
   ListView1->BeginUpdate();

   for (int i = 0; i < ListView1->Items->Count; i++)
      {

      TListViewItem * item = ListView1->Items->operator [](i);
      String Zakuski = item->Data[L"category"].AsString();
      if(Zakuski == L"Cold starters")
        {
         ListView1->Items->Item[i]->Height = 200;
        }
        else
           {
            ListView1->Items->Item[i]->Height = 0;
           }

      }

  }
  __finally
    {
     ListView1->EndUpdate();
    }


  MultiView1->HideMaster();
}


Why ListView1->Items->Item[i]->Height = 0; does not work?
It works ListView1->Items->Item[i]->Height = 500;
Why can not set the height equal =0???
Lena
BCBJ Master
BCBJ Master
 
Posts: 519
Joined: Sun Feb 06, 2011 1:28 pm

Re: ListView1->Items->Item[i]->Height = 0???

Postby rlebeau » Fri Oct 27, 2017 11:46 am

Lena wrote:
Code: Select all
ListView1->BeginUpdate();


That should be *above* the try block, not inside of it.

Lena wrote:
Code: Select all
TListViewItem * item = ListView1->Items->operator [](i);


You should not be calling operator[] directly like that. Use this instead:

Code: Select all
TListViewItem * item = (*(ListView1->Items))[i];


Or this (like you do in the rest of your code:

Code: Select all
TListViewItem * item = ListView1->Items->Item[i];


Lena wrote:
Code: Select all
ListView1->Items->Item[i]->Height = ...;


You should be using the item pointer you retrieved earlier:

Lena wrote:
Code: Select all
item->Height = ...;


Lena wrote:Why can not set the height equal =0???


Because FireMonkey simply does not support that. If an item's Height is <= 0, TListView renders it using a default Height instead. The smallest you can set the Height to is 1, but TListView will still render the separators between items, which will produce a bad visual effect.

You can't hide ListView items by simply setting their Height to 0. If you want to toggle the visibility of particular items, you have to remove them from, and add them to, the ListView dynamically. As such, don't store your actual data in the TListView. Use a separate list to keep track of the full data, and then use TListView to display only the data that should be visible to the user.
Last edited by rlebeau on Mon Oct 30, 2017 1:46 pm, edited 1 time in total.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1449
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: ListView1->Items->Item[i]->Height = 0???

Postby Lena » Sun Oct 29, 2017 2:05 am

Thank You.
When the program starts I have to show the full list of menus of all dishes. Then, if the user chooses to select a category through MultiView.

Use a separate list to keep track of the full data


What kind of list do you recommend? May be I need save all dishes in map?
std::map<String, std::vector<int> > IniContent;
key=name
vector1=price
vector2=how many
vector3=image visible 0/1
Attachments
sp.jpg
sp.jpg (31.94 KiB) Viewed 323 times
Lena
BCBJ Master
BCBJ Master
 
Posts: 519
Joined: Sun Feb 06, 2011 1:28 pm

Re: ListView1->Items->Item[i]->Height = 0???

Postby Lena » Mon Oct 30, 2017 6:48 am

You should not be calling operator[] directly like that. Use this instead:


TListViewItem * item = *(ListView1->Items)[i];
[bcc32 Error] UnitDibocca.cpp(65): E2093 'operator*' not implemented in type 'TAppearanceListViewItems' for arguments of the same type

TListViewItem * item = ListView1->Items->Item[i];
[bcc32 Error] UnitDibocca.cpp(64): E2034 Cannot convert 'TListItem *' to 'TListViewItem *'

But with this code everything is fine and there are no errors:
TListViewItem * item = ListView1->Items->operator [](i);
Lena
BCBJ Master
BCBJ Master
 
Posts: 519
Joined: Sun Feb 06, 2011 1:28 pm

Re: ListView1->Items->Item[i]->Height = 0???

Postby rlebeau » Mon Oct 30, 2017 1:54 pm

Lena wrote:When the program starts I have to show the full list of menus of all dishes. Then, if the user chooses to select a category through MultiView.


Like I said earlier, store the full data elsewhere in memory, using whatever container suits your needs. Then you can loop through that container whenever needed, adding only visual items to the TListView. So, at startup, loop through the container adding all items. Then, when the user selects a category, clear the TListView and loop through the container again, adding only the items that match the category.

Lena wrote:What kind of list do you recommend? May be I need save all dishes in map?


I would not use a std::map, unless sorting by Name is important to you. Since the data is being displayed in a TListView, a std::vector or std::list might make more sense.

Lena wrote:std::map<String, std::vector<int> > IniContent;
key=name
vector1=price
vector2=how many
vector3=image visible 0/1


I would not use an inner vector like that. A simple struct would suffice:

Code: Select all
struct myValues
{
    double price;
    int howMany;
    bool imageVisible;
};

std::map<String, myValues> IniContent;


Or:

Code: Select all
struct myValues
{
    String name;
    double price;
    int howMany;
    bool imageVisible;
};

std::vector<myValues> IniContent;
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1449
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: ListView1->Items->Item[i]->Height = 0???

Postby Lena » Tue Oct 31, 2017 5:06 am

Thank you for the recommendation!
Lena
BCBJ Master
BCBJ Master
 
Posts: 519
Joined: Sun Feb 06, 2011 1:28 pm

Re: ListView1->Items->Item[i]->Height = 0???

Postby rlebeau » Tue Oct 31, 2017 1:31 pm

Lena wrote:TListViewItem * item = *(ListView1->Items)[i];
[bcc32 Error] UnitDibocca.cpp(65): E2093 'operator*' not implemented in type 'TAppearanceListViewItems' for arguments of the same type


The subscript operator has a higher precedence than the dereference operator, so the above code is invoking the subscript operator first on the Items pointer, thus returning a reference to an (invalid when i != 0) TAppearanceListViewItems object, and then invoking the dereference operator on that object, thus the error since no such operator is implemented in that class.

You need an extra set of parenthesis to tell the compiler to dereference the Items pointer first, then invoke the subscript operator on the TAppearanceListViewItems object:

Code: Select all
TListViewItem * item = (*(ListView1->Items))[i];


You also need an extra type-cast, since the subscript operator returns a TListItem* pointer, not a TListViewItem* pointer:

Code: Select all
TListViewItem * item = static_cast<TListViewItem*>((*(ListView1->Items))[i]);


Lena wrote:TListViewItem * item = ListView1->Items->Item[i];
[bcc32 Error] UnitDibocca.cpp(64): E2034 Cannot convert 'TListItem *' to 'TListViewItem *'


You need an extra type-cast here, too:

Code: Select all
TListViewItem * item = static_cast<TListViewItem*>(ListView1->Items->Item[i]);


Lena wrote:But with this code everything is fine and there are no errors:
TListViewItem * item = ListView1->Items->operator [](i);


Well, there is one error, because operator[] (which just calls Item[] internally) returns a TListItem* pointer, which can't be assigned as-is to a TListViewItem* pointer. So, even if you invoke the operator directly (which is no better than just using the Items[] property), you still need a type-cast:

Code: Select all
TListViewItem * item = static_cast<TListViewItem*>(ListView1->Items->operator [](i));


The type-casts are needed due to the ListView refactoring in RADStudio 10.0 Seattle.
Remy Lebeau (TeamB)
Lebeau Software
User avatar
rlebeau
BCBJ Author
BCBJ Author
 
Posts: 1449
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA

Re: ListView1->Items->Item[i]->Height = 0???

Postby Lena » Wed Nov 01, 2017 2:53 am

Thank you for your help on the forum!
I used now:
Code: Select all
TListViewItem * item = static_cast<TListViewItem*>(ListView1->Items->Item[i]);

instead:
Code: Select all
TListViewItem * item = ListView1->Items->operator [](i);
Lena
BCBJ Master
BCBJ Master
 
Posts: 519
Joined: Sun Feb 06, 2011 1:28 pm


Return to Technical

Who is online

Users browsing this forum: Google [Bot] and 6 guests