VerticalStackList #2262
Replies: 7 comments 6 replies
-
Firstly thank you for the proposal, I like the idea of simplifying the code that developers have to write in order to achieve their goals and this looks to help there. I have a couple of questions:
|
Beta Was this translation helpful? Give feedback.
-
Thanks @bijington. In answer to your questions:
|
Beta Was this translation helpful? Give feedback.
-
At the core, your issue is really about customizable separators. In the case of custom vertical separators this can be done now by including the separators with your DataTemplate with an appropriate IsVisible trigger: <VerticalStackLayout>
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
<x:String>Item 3</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="x:String">
<VerticalStackLayout>
<BoxView x:Name="separator" HeightRequest="2" Color="Grey">
<BoxView.Triggers>
<DataTrigger Binding="{Binding .}" TargetType="BoxView" Value="Item 1">
<Setter Property="IsVisible" Value="False" />
</DataTrigger>
</BoxView.Triggers>
</BoxView>
<Label Text="{Binding .}" />
</VerticalStackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout> Note: The code snippet above uses hard-coded lists and constants to contribute to the discussion in a succinct manner. It has obvious flaws, particularly a lack of generalization. |
Beta Was this translation helpful? Give feedback.
-
I would say this is so easy to implement in a project, as shown by @stephenquan, that we shouldn't implement it here. Adding features to this lib will add overhead on maintainers, because it's one more feature, API to support and care about, I recommend this article to take a sense of what I'm saying |
Beta Was this translation helpful? Give feedback.
-
I agree with @bijington that ideally this should be baked into |
Beta Was this translation helpful? Give feedback.
-
@velocitysystems the DataTrigger intended to demonstrate that we can turn off the separator for the first item in the list. Certainly, there are better ways to achieve this, for instance I have an upcoming enhancement to the MultiMathExpressionConverter which could be used instead of the DataTrigger. As to whether the code belongs in the DataTemplate or not. Ultimately, it has to, because you need to make a decision on how each item in your list is being rendered, i.e. vertical vs horizontal vs bottom-up vs right-to-left. Also, you need to generalize between BindableLayout, ListView, CollectionView, ... To date, we have been making linear 1-D representation assumptions. What if a 2-D grid layout with horizontal and vertical separators is required? These factors would go beyond adding a mere Presently, the CommunityToolkit does have a DockLayout https://learn.microsoft.com/en-us/dotnet/communitytoolkit/maui/layouts/docklayout which would be the closest thing to a customizable/generalizable separator view (i.e. either an application of the DockLayout or the creation of a new component whose design is a derivative of DockLayout). The DockLayout together with the upcoming MultiMathExpressionConverter PR will look like this: <VerticalStackLayout BindableLayout.ItemsSource="{Binding MyItems, Source={Reference vm}}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="x:String">
<toolkit:DockLayout>
<BoxView
toolkit:DockLayout.DockPosition="Top"
HeightRequest="2"
Color="Grey"
IsVisible="{MultiBinding {Binding .},
{Binding MyItems[0], Source={Reference vm}},
Converter={StaticResource MultiMathExpressionConverter},
ConverterParameter='x0 != x1'}"/>
<Label Text="{Binding .}" />
</toolkit:DockLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout> Alternatively, you could consider using DataTemplateSelector https://learn.microsoft.com/en-us/dotnet/api/microsoft.maui.controls.datatemplateselector?view=net-maui-8.0 where one DataTemplate is used only for the first item in the list and the remaining items will use a default DataTemplate. Here's another solution involving ContentView. We provide two ControlTemplates. One ControlTemplate without the separator (for the first item), the other ControlTemplate with the separator for all other items. By using ContentPresenter, the user can supply their own visual element for rendering their item: <VerticalStackLayout BindableLayout.ItemsSource="{Binding MyItems, Source={Reference vm}}">
<VerticalStackLayout.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="first">
<ContentPresenter />
</ControlTemplate>
<ControlTemplate x:Key="default">
<toolkit:DockLayout>
<BoxView toolkit:DockLayout.DockPosition="Top" HeightRequest="2" Color="Grey" />
<ContentPresenter />
</toolkit:DockLayout>
</ControlTemplate>
</ResourceDictionary>
</VerticalStackLayout.Resources>
<BindableLayout.ItemTemplate>
<DataTemplate>
<ContentView ControlTemplate="{StaticResource first}">
<ContentView.Triggers>
<DataTrigger
Binding="{MultiBinding {Binding},
{Binding MyItems[0], Source={Reference vm}},
Converter={StaticResource MultiMathExpressionConverter},
ConverterParameter='x0 != x1'}"/>
TargetType="ContentView"
Value="True">
<Setter Property="ControlTemplate" Value="{StaticResource default}" />
</DataTrigger>
</ContentView.Triggers>
<Label Text="{Binding .}" />
</ContentView>
</DataTemplate>
</BindableLayout.ItemTemplate>
</VerticalStackLayout> |
Beta Was this translation helpful? Give feedback.
-
Created feature request to add |
Beta Was this translation helpful? Give feedback.
-
Summary
This control extends
VerticalStackLayout
+BindableLayout
and provides support for item separators normally only available in aListView
. The control also dynamically allows data to be added/removed using theINotifyCollectionChanged
events on anObservableCollection<T>.
This allows for placement of this list within a parent
ScrollView
which is normally an 'anti-pattern' for aListView
orCollectionView
. However this is a common design element in many UX designs i.e. inline lists.Design
Usage
Output
For strings: "Foo", "Bar" result would be:
Note: I already have a fully-built version of this control. I wanted to submit this as a feature proposal since I think it would make a worthy addition to the toolkit.
Beta Was this translation helpful? Give feedback.
All reactions