首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >滚动视图中比例网格行中的Maui Listview

滚动视图中比例网格行中的Maui Listview
EN

Stack Overflow用户
提问于 2022-10-29 09:53:50
回答 4查看 197关注 0票数 0

我在网格成比例行中使用listview,它的其他元素在自动行中。因为我希望我的列表能占据屏幕的其余部分。到目前为止一切都很正常。

但是,当我想在外部使用滚动视图时,列表视图占据了整个屏幕,其他元素不可见。

我希望列表视图在滚动视图中显示为相同。这里我必须使用滚动视图,因为我添加了更多的元素(标签、按钮等)。在网格中的动态。一段时间后,当listview高度达到末尾时,滚动视图就会启动。我什么都试了,但都失败了

非常感谢那些到目前为止提供帮助的人。

示例代码

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp4.MainPage">
    <ScrollView VerticalOptions="Fill">
        <Grid HorizontalOptions="Fill" VerticalOptions="Fill">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Image
                Source="dotnet_bot.png"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                HeightRequest="200"
                HorizontalOptions="Center" />

            <Label Grid.Row="1"
                Text="Hello, World!"
                SemanticProperties.HeadingLevel="Level1"
                FontSize="32"
                HorizontalOptions="Center" />

            <ListView x:Name="listView" 
                          Grid.Row="2" 
                          VerticalOptions="Fill"
                          ItemsSource="{Binding Monkeys}"
                          MinimumHeightRequest="200">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.ContextActions>
                                <MenuItem Text="Favorite"
                                      IconImageSource="favorite.png"
                                      Command="{Binding Source={x:Reference listView}, Path=BindingContext.FavoriteCommand}"
                                      CommandParameter="{Binding}" />
                                <MenuItem Text="Delete" 
                                      IconImageSource="delete.png"
                                      Command="{Binding Source={x:Reference listView}, Path=BindingContext.DeleteCommand}"
                                      CommandParameter="{Binding}" />
                            </ViewCell.ContextActions>

                            <Grid Padding="10">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                </Grid.ColumnDefinitions>
                                <Image Grid.RowSpan="2" 
                                   Source="{Binding ImageUrl}" 
                                   Aspect="AspectFill"
                                   HeightRequest="60" 
                                   WidthRequest="60" />
                                <Label Grid.Column="1" 
                                   Text="{Binding Name}" 
                                   FontAttributes="Bold" />
                                <Label Grid.Row="1"
                                   Grid.Column="1" 
                                   Text="{Binding Location}"
                                   FontAttributes="Italic" 
                                   VerticalOptions="End" />
                            </Grid>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

            <Label Grid.Row="3"
                Text="Welcome to .NET Multi-platform App UI"
                SemanticProperties.HeadingLevel="Level2"
                SemanticProperties.Description="Welcome to dot net Multi platform App U I"
                FontSize="18"
                HorizontalOptions="Center" />

            <Button Grid.Row="4"
                x:Name="CounterBtn"
                Text="Click me"
                SemanticProperties.Hint="Counts the number of times you click"
                Clicked="OnCounterClicked"
                HorizontalOptions="Center" />
        </Grid>
    </ScrollView>
</ContentPage>
EN

回答 4

Stack Overflow用户

发布于 2022-11-03 12:24:23

您希望您的"listview占据屏幕的其余部分“,同时,您将这个网格包装在一个ScrollView中,从而消除了限制。

不要将垂直ListView包装在垂直ScrollView中。或者,如果你这样做,确保你的ListView的高度是有限的。

否则,您将在完全扩展的ListView上滚动。

票数 0
EN

Stack Overflow用户

发布于 2022-11-04 07:37:12

您可以将列表视图所在的行设置为绝对高度

以下是代码:

代码语言:javascript
运行
复制
<ScrollView>
        <Grid RowDefinitions="auto,auto,200,auto,auto,auto,auto">
       <Image Grid.Row="0"
                Source="dotnet_bot.png"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                HeightRequest="200"
                HorizontalOptions="Center" />
       <Label Grid.Row="1"
                Text="Hello, World!"
                SemanticProperties.HeadingLevel="Level1"
                FontSize="32"
                HorizontalOptions="Center" />
        <ListView Grid.Row="2">
            <ListView.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                    <x:String>sss</x:String>
                </x:Array>
            </ListView.ItemsSource>
        </ListView>
       <Label Grid.Row="3"
                Text="Welcome to .NET Multi-platform App UI"
                SemanticProperties.HeadingLevel="Level2"
                SemanticProperties.Description="Welcome to dot net Multi platform App U I"
                FontSize="18"
                HorizontalOptions="Center" />
       <Button Grid.Row="4"
                x:Name="CounterBtn"
                Text="Click me"
                SemanticProperties.Hint="Counts the number of times you click"
                Clicked="OnCounterClicked"
                HorizontalOptions="Center" />
            <Image Grid.Row="5"
                Source="dotnet_bot.png"
                SemanticProperties.Description="Cute dot net bot waving hi to you!"
                HeightRequest="200"
                HorizontalOptions="Center" />
           <Label Grid.Row="6"
                Text="Hello, World!"
                SemanticProperties.HeadingLevel="Level1"
                FontSize="32"
                HorizontalOptions="Center" />
       </Grid>
    </ScrollView>
票数 0
EN

Stack Overflow用户

发布于 2022-11-05 12:32:52

我自己正在计算比例高度。

代码很简单,因为它是一个示例,这里不包括ViewModel。

如果任何人有其他想法,他们可以添加他们的想法。谢谢大家。

,这是最后的状态。

MainPage.xaml

代码语言:javascript
运行
复制
<Shell.TitleView>
    <Button Text="+ Add Random Element" Clicked="OnAddRandomElementButtonClicked" TextColor="White" />
</Shell.TitleView>
<Grid>
    <ScrollView  x:Name="MainScrollView" VerticalOptions="Fill" Margin="0">
        <StackLayout x:Name="MainStackLayout" />
    </ScrollView>
</Grid>

MainPage.xaml.cs

代码语言:javascript
运行
复制
public partial class MainPage : ContentPage
{
    double width;
    double height;
    int count = 0;

    List<MyElement> myElements = new List<MyElement>();

    public MainPage()
    {
        InitializeComponent();
        BindingContext = new MainPageViewModel();

        myElements.Add(new MyElement(MyElementType.Image, -1, 100, true));
        myElements.Add(new MyElement(MyElementType.Label, 30));
        myElements.Add(new MyElement(MyElementType.Entry, 35));
        myElements.Add(new MyElement(MyElementType.ListView, -1, 200, true));
        myElements.Add(new MyElement(MyElementType.Label, 35));
        myElements.Add(new MyElement(MyElementType.Button, 40));

        SizeChanged += (s, e) =>
        {
            if (Width != this.width || Height != this.height)
            {
                this.width = Width;
                this.height = Height;
                RenderContent();
            }
        };
    }

    private void OnAddRandomElementButtonClicked(object sender, EventArgs e)
    {
        Random rnd = new Random();
        int randIndex = rnd.Next(myElements.Count);
        var randomElement = myElements[randIndex];

        myElements.Add(randomElement);

        RenderContent();
    }

    void CalculateProportionalHeightAndUpdate()
    {
        double usedDisplayHeight = myElements.Where(e => e.IsProportional == false).Select(e => e.Height).Sum();
        double leftOverDisplayHeight= this.height - usedDisplayHeight;

        var proportionalElements = myElements.Where(e => e.IsProportional);
        if (proportionalElements.Any())
        {
            double heightForOneUnit = leftOverDisplayHeight/ proportionalElements.Count();
            foreach (var element in proportionalElements)
                element.Height = Math.Max(element.MinHeight, heightForOneUnit); // Minimum height
        }
    }

    void RenderContent()
    {
        CalculateProportionalHeightAndUpdate();

        Grid grid = new Grid();
        foreach (var element in myElements)
            grid.RowDefinitions.Add(new RowDefinition() { Height = element.Height });

        int row = 0;
        foreach (var element in myElements)
        {
            VisualElement visualElement = element.ElementType switch
            {
                MyElementType.Label => CreateLabel(element.Height),
                MyElementType.ListView => CreateListView(element.Height),
                MyElementType.Button => CreateButton(element.Height),
                MyElementType.Image => CreateImage(element.Height),
                _ => CreateEntry(element.Height)
            };
            grid.Add(visualElement, 0, row);
            row++;
        }
        MainStackLayout.Children.Clear();
        MainStackLayout.Add(grid); //Since scrollview is not active with dynamic content, I added the grid in stacklayout.
    }

    Entry CreateEntry(double height = 40) => new Entry { Placeholder = "Enter text here", HeightRequest = height, HorizontalOptions = LayoutOptions.Center };

    Image CreateImage(double height = 100)
    {
        return new Image
        {
            Source = "dotnet_bot.png",
            HeightRequest = height,
            HorizontalOptions = LayoutOptions.Center
        };
    }

    ListView CreateListView(double height = -1)
    {
        var listView = new ListView
        {
            HeightRequest = height,
            VerticalOptions = LayoutOptions.Fill
        };

        listView.SetBinding(ListView.ItemsSourceProperty, "Monkeys");

        listView.ItemTemplate = new DataTemplate(() =>
        {
            Grid grid = new Grid { Padding = 10 };
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
            grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

            Image image = new Image { Aspect = Aspect.AspectFill, HeightRequest = 60, WidthRequest = 60 };
            image.SetBinding(Image.SourceProperty, "ImageUrl");

            Label nameLabel = new Label { FontAttributes = FontAttributes.Bold };
            nameLabel.SetBinding(Label.TextProperty, "Name");

            Label locationLabel = new Label { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.End };
            locationLabel.SetBinding(Label.TextProperty, "Location");

            Grid.SetRowSpan(image, 2);

            grid.Add(image);
            grid.Add(nameLabel, 1, 0);
            grid.Add(locationLabel, 1, 1);

            return new ViewCell { View = grid };
        });

        return listView;
    }

    Label CreateLabel(double height = 30) => new Label { Text = "Hello, World!", HeightRequest = height, HorizontalOptions = LayoutOptions.Center };

    Button CreateButton(double height = 40)
    {
        var button = new Button { Text = "Click me", HeightRequest = height, HorizontalOptions = LayoutOptions.Center };
        button.Clicked += (s, e) => OnCounterClicked(s, e, button);
        return button;
    }

    private void OnCounterClicked(object sender, EventArgs e, Button button)
    {
        count++;

        if (count == 1)
            button.Text = $"Clicked {count} time";
        else
            button.Text = $"Clicked {count} times";

        SemanticScreenReader.Announce(button.Text);
    }
}

public class MyElement
{
    public MyElement(MyElementType elementType, double height, double minHeight = -1, bool isProportional = false)
    {
        ElementType = elementType;
        Height = height;
        MinHeight = minHeight == -1 ? height : minHeight;
        IsProportional = isProportional;
    }
    public double Height { get; set; }
    public double MinHeight { get; set; }
    public MyElementType ElementType { get; set; }
    public bool IsProportional { get; set; }
}

public enum MyElementType
{
    Label,
    Button,
    ListView,
    Image,
    Entry
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74244322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档