sbaeumlisberger / VirtualizingWrapPanel

Implementation of a comprehensive VirtualisingWrapPanel for WPF
MIT License
254 stars 35 forks source link

Dynamic Item Size #50

Closed Ross-Patterson closed 10 months ago

Ross-Patterson commented 10 months ago

Version Info Package Version: 2.0.0 Preview 4

Describe your issue Is there support for a dynamic item size? i.e. user can choose the item width/height.

As far as I can see if you bind to ItemSize, it doesn't update when the size changes, or some max limit is reached.

I also tried implementing IItemSizeProvider, but it seems to only calculate initially, any way to force a recalculation?

Thanks!

sbaeumlisberger commented 10 months ago

Hi, binding to the ItemSize property should work fine (I just tested it). The interface ItemSizeProvider is only intended for use if the property AllowDifferentSizedItems is enabled.

If you still have an issue with the ItemSize property, let me know how to reproduce it. Thank you.

Ross-Patterson commented 10 months ago

Take a look at the attached test project & video.

As you move the height slider, it seems to me that the size is not being reflected/recalculated, as the scrollbar size is wrong.

This is using AllowDifferentSizedItems True and implementing IItemSizeProvider.

https://github.com/sbaeumlisberger/VirtualizingWrapPanel/assets/66630787/8d33fc2e-af6c-4951-afe1-da28ac0cdc3a

VirtualizingWrapPanelTest.zip

Ross-Patterson commented 10 months ago

Update: So using AllowDifferentSizedItems = False and not using IItemSizeProvider but instead binding to ItemSize works but the default ListViewItem template seems to cause issues (this seems to be consistent with other implementations of VirtualizingWrapPanel i.e. BinaryMission), where the content (ItemTemplate) doesn't size correctly within the ListViewItem when the size is changed.

I had to re-implement the ListViewItem template from scratch - then bind to ItemSize, when it works as I expect.

Using Default ListViewItem template:

https://github.com/sbaeumlisberger/VirtualizingWrapPanel/assets/66630787/c553b259-8bf1-4045-a646-499a1f3a8d63

Using Re-Implemented ListViewItem Template (just a Border with a ContentPresenter inside):

https://github.com/sbaeumlisberger/VirtualizingWrapPanel/assets/66630787/7b0687f6-69f2-4762-9ae9-2bc22085fc98

sbaeumlisberger commented 10 months ago

Right you need to remove the AllowDifferentSizedItems property or set it to false, because if the property is enabled, the item sizes will be cached.

Then you can use the ItemSize property or just bind to the Width and Height properties inside your ItemTemplate. I actually noticed a problem when decreasing the ItemSize property, so for the moment it might be better to bind to the Width and Height properties.

Indeed the default container template has some issues, but it should be sufficient to add the following properties to your ItemContainerStyle:

<ListView.ItemContainerStyle>
  <Style TargetType="ListViewItem">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    ...
   <Style TargetType="ListViewItem">
<ListView.ItemContainerStyle>
Ross-Patterson commented 10 months ago

It worked a treat by doing as you said - also removing the default padding that the ListViewItem has:

<ListView.ItemContainerStyle>
  <Style TargetType="ListViewItem">
    <Setter Property="Padding" Value="0" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    ...
   <Style TargetType="ListViewItem">
<ListView.ItemContainerStyle>

Thanks a lot!

sbaeumlisberger commented 10 months ago

Glad we've found a solution.

The problem with decreasing the ItemSize property has also been fixed and will be released soon.