For me (on my tests) seems to finally works OK now:

For VirtualList:

public function refresh():void
{
var index:int = selectedIndex;
var top:int = element.scrollTop;

var oldDataProvider:Object = dataProvider;
dataProvider = null;
dataProvider = oldDataProvider;

if ((dataProvider as IArrayList).length > 0)
{
selectedIndex = index;
element.scrollTop = top;
//during the tests I found some inconsistence, so it's need a delay before
select the item
setTimeout(function():void
{
var itemRenderer:IItemRenderer = (view as
VirtualListView).getItemRendererForIndex(selectedIndex);
if (itemRenderer != null)
itemRenderer.element.click();
}, 500);
setFocus();
}
}

For VirtualDataGrid I'm using an addition component to add buttons on my
bottom of the Grid with the following and working good functions:

private function onAddClicked():void
{
var entity:Object = new modelType();
if (dataGrid.dataProvider is EntityList && entity is IEntity)
(dataGrid.dataProvider as EntityList).addEntity(entity as IEntity);
else
(dataGrid.dataProvider as ArrayList).addItem(entity);

if (dataGrid.dataProvider is EntityList)
(dataGrid.dataProvider as EntityList).refresh();

dataGrid.selectedIndex = (dataGrid.dataProvider as ArrayList).length - 1;

var scrollHeight:int = dataGrid.element.children.item(1).children.item(0
).scrollHeight;
for each (var item:* in dataGrid.element.children.item(1).children)
{
item.scrollTop = scrollHeight;
}

dispatchEvent(new Event(ADDED));
}

private function onRemoveClicked():void
{
var index:int = dataGrid.selectedIndex;
var top:int = dataGrid.element.children.item(1).children.item(0).scrollTop;

if (dataGrid.dataProvider is EntityList && dataGrid.selectedItem is IEntity)
(dataGrid.dataProvider as EntityList).deleteEntity(dataGrid.selectedItem as
Entity);
else
(dataGrid.dataProvider as ArrayList).removeItem(dataGrid.selectedItem);

if (dataGrid.dataProvider is EntityList)
(dataGrid.dataProvider as EntityList).refresh();

dataGrid.selectedIndex = index;

for each (var item:* in dataGrid.element.children.item(1).children)
{
item.scrollTop = top;
}

dispatchEvent(new Event(DELETED));
}


EntityList , IEntity and Entity are classes of my own AS3-ORM.

Maria Jose Esteve <mjest...@iest.com> escreveu no dia sábado, 21/10/2023
à(s) 17:19:

> Hi Hugo,
> Yes, that problem has given me a lot of headaches and "in the end" it was
> stronger than me.
> As I see that you are also with this issue I could reactivate it and see
> if, between the two of us, we can give a good solution (I think we have
> discussed this same issue several times in this list and in the users list).
>
> In my case I took as reference Jewel List and its "scrollToIndex" (that we
> debugged it with Carlos some time ago).
> From my point of view, when you refresh the dataprovider, as well as when
> you assign a selectedIndex, the list must be positioned in that element and
> make it visible.
>
> I managed to solve it in VirtualComboBox but with the VirtualList it
> didn't work too well; moreover, if the control "is not visible" when the
> dataprovider is assigned, the elements are NOT CREATED correctly. I know I
> was close to the solution, but I was stuck and, at the time, there were no
> people using these controls and they couldn't give me any additional
> support.
>
> I seem to remember that I implemented and debugged it in the
> royal-examples-community project but my memory may fail me....
>
> I will be happy to try to solve these problems together with you, I don't
> have much time now, but I can try again with you if you agree.
>
> Let me know if we can do it and I will look for the implementation.
> Hiedra
>
> -----Mensaje original-----
> De: Hugo Ferreira <hferreira...@gmail.com>
> Enviado el: sábado, 21 de octubre de 2023 12:17
> Para: dev@royale.apache.org
> Asunto: Function to refresh a VirtualList
>
> Hi,
>
> I didn't post on Royale mailing list for a while.
> Very busy.
>
> I use VirtualList and VirtualDataGrid however they are not perfect.
>
> One thing that always bothered me was that if I need for example to remove
> an element of the list, then I need to refresh the dataProvider and I have
> to notify the List, losing the selectedItem and scroll position. This gives
> a very bad experience to the user.
>
> I finally put time on this and did this working for me.
> Works on the top item (the easy ones), works on the middle of the list
> (the chalange ones because it's a Virtual container) and also works for the
> last item.
> The code it's not 100% beatutifull for the eye (the reason to not push to
> the repository), however the issue is also chalanging.
> If someone have the same issue as I did, here my solution (for now).
> Next I will do the same for DataGrid and should be similar to this
> solution.
>
> If someone have a more elegant solution or find out an improvement that I
> missed, please reply.
>
> public function refresh():void
> {
> var index:int = selectedIndex;
> var top:int = element.scrollTop;
>
> var oldDataProvider:Object = dataProvider; dataProvider = null;
> dataProvider = oldDataProvider;
>
> if ((dataProvider as IArrayList).length > 0) { selectedIndex = index;
> element.scrollTop = top; //during the tests I found some inconsistence, so
> it's need a delay before select the item setTimeout(function():void { var
> itemRenderer:IItemRenderer = (view as
> VirtualListView).getItemRendererForIndex(selectedIndex);
> if (itemRenderer != null)
> itemRenderer.element.click();
> }, 500);
> setFocus();
> }
> }
>

Reply via email to