ListView 项目在 Xamarin 表单中不展开折叠高度

Posted

技术标签:

【中文标题】ListView 项目在 Xamarin 表单中不展开折叠高度【英文标题】:ListView Item doesn't expand-collapse height in Xamarin Forms 【发布时间】:2018-12-07 18:19:42 【问题描述】:

我有一个列表视图。在 ListView 我有 ListViewCell。 ListViewCell 具有展开折叠功能。展开折叠行为的问题很少。

1- 如果我展开第一项,它工作正常。但是,如果我先展开第二项并展开第一项,则第一项落后。请参阅屏幕截图中的案例 1。

2- 如果我单击列表视图项,它会以灰色显示一秒钟。我想阻止这一切。当用户单击任何单元格时,它不应更改和着色。案例2

3- 如果我展开第一个项目并再次折叠它。它会折叠,但会在第二项和第一项之间保留空白。

我注意到了这种行为。如果我向下和向上滚动,上述问题将解决。好吧,在理想情况下,用户不会在每次操作后上下滚动:D

注意:我在 ListViewCell 中有条目、日期选择器和按钮。用户必须能够输入。

这是我的代码。我还附上了屏幕截图。请推荐

主页列表视图

<ListView x:Name="WorkHistoryListView"
    ItemsSource="Binding WorkHistoryList"
    HorizontalOptions="FillAndExpand"
    VerticalOptions="FillAndExpand"
    SeparatorVisibility="None"
    ItemTapped="OnListViewItemTapped"
    Margin="10"
    HasUnevenRows = "true"
    IsPullToRefreshEnabled="False">
    <ListView.ItemTemplate>
        <DataTemplate>
            <localview:WorkHistoryViewCell />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

WorkHistoryViewCell.xaml

<StackLayout Margin="0" Padding="0">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <!-- Blue heading-->
        <StackLayout Margin="0" Padding="0" Grid.Row="0" BackgroundColor="#367fa9">
            <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" 
      Padding="15" RowSpacing="10" Margin="0" BackgroundColor="Transparent">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="auto"/>
                    <RowDefinition Height="auto"/>
                </Grid.RowDefinitions>

                <Label Text="Binding Name" HorizontalOptions="Center" Grid.Column="0" Grid.Row="0"/>
                <Label Text="Binding Date" HorizontalOptions="Center" Grid.Column="1" Grid.Row="1"/>
                <Label Text="+" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="2" x:Name="LabelCollapse" Grid.Row="0" Grid.RowSpan="2" FontFamily="Roboto">
                    <Label.GestureRecognizers>
                        <TapGestureRecognizer Tapped="LabelOpenCommand"/>
                    </Label.GestureRecognizers>
                </Label>
            </Grid>
        </StackLayout>
        <StackLayout Margin="0" Padding="0" Grid.Row="1" x:Name="FrameVisible">
            <Frame Margin="0" Padding="0" HorizontalOptions="FillAndExpand" BackgroundColor="White" OutlineColor="Gray">
                <StackLayout Margin="0" VerticalOptions="Fill" Padding="20" IsVisible="Binding IsWeekly">
                    <Grid>
                        <Grid.Resources>
                            <ResourceDictionary>
                                <local:InvertBooleanConverter x:Key="invertBooleanConverter" />
                                <Style x:Key="LabelStyle" TargetType="Label">
                                    <Setter Property="FontSize" Value="15"/>
                                    <Setter Property="FontFamily" Value="Roboto"/>
                                    <Setter Property="TextColor" Value="White"/>
                                </Style>
                            </ResourceDictionary>
                        </Grid.Resources>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="125"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto"></RowDefinition>
                            <RowDefinition Height="auto"></RowDefinition>
                            <RowDefinition Height="auto"></RowDefinition>
                            <RowDefinition Height="auto"></RowDefinition>
                            <RowDefinition Height="auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Image Source="EditLog.png" Grid.Column="1" Grid.Row="0" HorizontalOptions="End" VerticalOptions="Center"
                                HeightRequest="24">
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer Tapped="OnImageViewItemTapped"/>
                            </Image.GestureRecognizers>
                        </Image>
                        <Label Text="Date" Grid.Column="0" Grid.Row="0" Style="StaticResource LabelStyle" 
                               TextColor="Black" FontFamily="Roboto" Margin="0" />
                        <local:ExtendedDatePicker TextColor="LightGray" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
                            IsEnabled="False" Date="Binding Date" BackgroundColor="White">
                            <DatePicker.Format>dd/MM/yyyy</DatePicker.Format>
                        </local:ExtendedDatePicker>

                        <Label Text="Pay" Grid.Column="0" Grid.Row="2"  Style="StaticResource LabelStyle"
                               TextColor="Black" FontFamily="Roboto" Margin="0,10,0,0" />

                        <local:CustomEntry Grid.Column="0" Grid.Row="3" Margin="0,10,0,0" WidthRequest="150" Text="Binding Pay"
                            Style="StaticResource LabelStyle" TextColor="Black"  HorizontalOptions="EndAndExpand" VerticalOptions="FillAndExpand"/>

                        <Button Text="Submit" BorderRadius="18" TextColor="White" Command="Binding SubmitWeeklyCommand" Grid.Column="0" Grid.Row="4" FontFamily="Roboto"/>
                    </Grid>
                </StackLayout>
            </Frame>
        </StackLayout>
    </Grid>
</StackLayout>

WorkHistoryViewCell.xaml.cs //命令展开折叠

private void LabelOpenCommand(object sender,TappedEventArgs e)

    if (LabelCollapse.Text == "+")
    
        FrameVisible.IsVisible = false;
        LabelCollapse.Text = "-";
        FrameVisible.IsVisible = true;
    
    else
    
        FrameVisible.IsVisible = true;
        LabelCollapse.Text = "+";
        FrameVisible.IsVisible = false;
    

截图

【问题讨论】:

【参考方案1】:

发生这种情况是因为 单元格的高度 仅在第一次渲染时计算。之后,更改只影响内部布局视图。

尝试在当前TappedCommand 的逻辑结束时调用ForceUpdateSize();。它将强制整个单元格重新计算其边界。

代码应如下所示:

private void LabelOpenCommand(object sender,TappedEventArgs e)

    if (LabelCollapse.Text == "+")
    
        FrameVisible.IsVisible = false;
        LabelCollapse.Text = "-";
        FrameVisible.IsVisible = true;
    
    else
    
        FrameVisible.IsVisible = true;
        LabelCollapse.Text = "+";
        FrameVisible.IsVisible = false;
    

    ForceUpdateSize

希望对你有帮助。

【讨论】:

谢谢。 ForceUpdateSize 需要 2-3 秒才能获得更新的大小。通常,Accordian 不应该占用这样的时间,因为存在操作而不是隐藏显示。所以,如果有人问我为什么要花时间,很难解释。请提出您的想法! 确实不需要太多时间。整个ViewCell 看起来很沉重,但即使如此,2-3 秒也是不可接受的。您是否尝试过异步执行此操作?你是在为@Developer说话吗? @DiegoRafaelSouza 我也对此进行了审查。第一次,它需要 1-2 秒,我想这很好。如果用户尝试展开折叠 2-3 次,它会变得非常慢,需要 3-4 秒才能展开折叠。此延迟问题仅适用于 ios。它在 UWP 和 android 中运行良好。我认为它在 iOS 中应该可以正常工作,因为它是我们的主要目标。你提到了异步。我怎样才能做到这一点?我已经按照您在回答中给出的确切代码。你能用异步代码更新你的答案吗?谢谢。 @Developer 很抱歉迟到了。只是将方法的签名更改为private async void LabelOpenCommand(...) ... 。 iOS上没试过,安卓上就试过了,反应也够快的。 @DiegoRafaelSouza,这没有任何改变。是的,你是对的,它在 Android 中运行得非常快。在 iOS 中仍然需要时间。我试图将这一行 CachingStrategy="RecycleElement 放在我的 Listview 中,它开始正常工作。但是它引发了另一个问题:当我展开第一个项目(viewcell)时,它还会展开下一个屏幕上的其他单元格。有什么建议吗?

以上是关于ListView 项目在 Xamarin 表单中不展开折叠高度的主要内容,如果未能解决你的问题,请参考以下文章

如何选择项目 MVVM listview - Xamarin 表单

添加列表框项目在 xamarin 表单中不起作用

ListView 内的 Xamarin 表单按钮命令绑定

更新 ObservableCollection 无法正确更新 Xamarin 表单中的 ListView

预选的 CollectionView 在 xamarin 表单中不起作用

如何知道 ListView 中修改了哪个 Xamarin 表单条目?