Как создать ScrollView в этом макете?

Nov 09 2020

Мне нужно создать ScrollView в этом макете, но проблема в том, что мой элемент управления занимает весь экран, и я не знаю, как заставить его занимать только тот размер, который у него есть. Это функциональность элемента управления

Мне нужно, чтобы он не заполнял весь экран, а только его собственный размер, чтобы можно было добавить больше вещей в макет

Это XAML моего контроля:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="ControlProject.CustomControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="CustomView">

    <ContentView.Content>

        <AbsoluteLayout>
            <!--  ================This is the entry that must be in the bottom================  -->
            <StackLayout
                x:Name="STACK"
                AbsoluteLayout.LayoutBounds="0,1,1,0.07"
                AbsoluteLayout.LayoutFlags="All"
                Orientation="Horizontal">
                <Frame
                    Margin="0,0,0,2"
                    Padding="0,0,0,0"
                    BackgroundColor="{Binding Source={x:Reference CustomView}, Path=FrameColor}"
                    BorderColor="{Binding Source={x:Reference CustomView}, Path=BorderColor}"
                    CornerRadius="{Binding Source={x:Reference CustomView}, Path=CornerRadius}"
                    HasShadow="False"
                    HorizontalOptions="FillAndExpand">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>


                        <ImageButton
                            Grid.Column="0"
                            Margin="5,0,0,0"
                            BackgroundColor="Transparent"
                            Clicked="Open"
                            HeightRequest="25"
                            HorizontalOptions="Start"
                            Source="{Binding Source={x:Reference CustomView}, Path=LeftSideIcon}" />


                        <Entry
                            x:Name="EntryControl"
                            Grid.Column="1"
                            Margin="0,0,55,0"
                            HeightRequest="25"
                            HorizontalOptions="FillAndExpand"
                            Keyboard="Chat"
                            Placeholder="{Binding Source={x:Reference CustomView}, Path=Placeholder}"
                            Text="{Binding EntryText}"
                            TextColor="{Binding Source={x:Reference CustomView}, Path=EntryTextColor}" />

                        <ImageButton
                            Grid.Column="1"
                            Margin="0,0,40,0"
                            BackgroundColor="Transparent"
                            Command="{Binding Source={x:Reference CustomView}, Path=DeleteMsgCommand}"
                            HeightRequest="25"
                            HorizontalOptions="End"
                            Source="{Binding Source={x:Reference CustomView}, Path=DeleteMessageIcon}" />

                        <ImageButton
                            Grid.Column="1"
                            Margin="0,0,10,0"
                            Padding="1"
                            BackgroundColor="Transparent"
                            Command="{Binding Source={x:Reference CustomView}, Path=InsertImgCommand}"
                            HeightRequest="25"
                            HorizontalOptions="End"
                            Source="{Binding Source={x:Reference CustomView}, Path=InsertImgIcon}" />


                    </Grid>
                </Frame>

                <ImageButton
                    Margin="0,0,5,2"
                    Padding="15,0,10,0"
                    BackgroundColor="{Binding Source={x:Reference CustomView}, Path=SendBtnColor}"
                    Command="{Binding Source={x:Reference CustomView}, Path=SendMsgCommand}"
                    CornerRadius="30"
                    HeightRequest="45"
                    HorizontalOptions="End"
                    Source="{Binding Source={x:Reference CustomView}, Path=RightSideIcon}"
                    WidthRequest="45" />

            </StackLayout>

            <!--  ================This is what it moves up================  -->
            <StackLayout
                x:Name="frameemojis"
                AbsoluteLayout.LayoutBounds="0,1,1,0.43"
                AbsoluteLayout.LayoutFlags="All"
                TranslationY="{Binding Height, Source={x:Reference frameemojis}}">


                <Frame>


                    <CollectionView
                        Margin="-10,-15,-10,-10"
                        HeightRequest="270"
                        ItemsSource="{Binding Source={x:Reference CustomView}, Path=EmojiItemSource}"
                        VerticalScrollBarVisibility="Never">

                        <CollectionView.ItemsLayout>
                            <GridItemsLayout Orientation="Horizontal" Span="5" />
                        </CollectionView.ItemsLayout>
                        <CollectionView.ItemTemplate>

                            <DataTemplate>

                                <ImageButton
                                    Padding="5"
                                    BackgroundColor="Transparent"
                                    Command="{Binding Source={x:Reference CustomView}, Path=EmojiTappedCommand}"
                                    CommandParameter="{Binding EmojiMethodCommand}"
                                    HeightRequest="44"
                                    Source="{Binding EmojiSource}"
                                    WidthRequest="44" />
                            </DataTemplate>
                        </CollectionView.ItemTemplate>

                    </CollectionView>
                </Frame>
                <!--  ==============  -->
            </StackLayout>

        </AbsoluteLayout>

    </ContentView.Content>
</ContentView>

MainPage.xaml (сюда я хочу добавить ScrollView):

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="App24.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:fav="clr-namespace:ControlProject;assembly=ControlProject">


    <AbsoluteLayout>
        <!--  This is where I want to add the scrollview  -->

        <StackLayout
            AbsoluteLayout.LayoutBounds="0,1,1,1"
            AbsoluteLayout.LayoutFlags="All"
            BackgroundColor="#4DFF0000">

            <fav:CustomControl
                x:Name="entrycontrol"
                BorderColor="{Binding EntryBorderColor}"
                CornerRadius="{Binding EntryRadius}"
                DeleteMessageIcon="crossblack.png"
                DeleteMsgCommand="{Binding DeleteMsgCommand}"
                EmojiItemSource="{Binding EmojiList}"
                EmojiTappedCommand="{Binding EmojiTappedCommand}"
                EntryTextColor="{Binding TextColor}"
                FrameColor="{Binding EntryBGColor}"
                InsertImgCommand="{Binding InsertImgCommand}"
                InsertImgIcon="insertimage.png"
                LeftSideIcon="icon.png"
                Placeholder="Escribddame"
                RightSideIcon="send.png"
                SendBtnColor="{Binding SendBtnColor}"
                SendMsgCommand="{Binding SendMsgCommand}" />
        </StackLayout>




    </AbsoluteLayout>

</ContentPage>

[ИЗМЕНИТЬ]

Метод управления кодом:

  bool isShow;
    const double layoutPropHeightMax = 0.45;
    const double layoutPropHeightMin = 0.06;
    private void Button_Clicked(object sender, EventArgs e)
    {
        if (!isShow)
        {
            //show the keyboard

            Device.BeginInvokeOnMainThread(async () =>
            {

                var height = layoutPropHeightMin;

                while (height < layoutPropHeightMax)
                {
                    await Task.Delay(1);
                    height += 0.04;

                    AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
                }

            });

        }

        else
        {
            // hide the keyboard
            Device.BeginInvokeOnMainThread(async () =>
            {

                var height = layoutPropHeightMax;

                while (height > layoutPropHeightMin)
                {
                    await Task.Delay(1);
                    height -= 0.04;

                    AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
                }

            });

        }


        isShow = !isShow;
    }

Контрольный XAML:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="ControlProject.CustomControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Name="CustomView">


    <AbsoluteLayout AbsoluteLayout.LayoutBounds="0,1,1,1" BackgroundColor="White">

        <StackLayout
            x:Name="bottomBar"
            AbsoluteLayout.LayoutBounds="0.5,1,1.0,0.07"
            AbsoluteLayout.LayoutFlags="All"
            BackgroundColor="Olive">


            <StackLayout
                x:Name="STACK"
                AbsoluteLayout.LayoutBounds="0,1,1,0.07"
                AbsoluteLayout.LayoutFlags="All"
                Orientation="Horizontal">
                <Frame
                    Margin="0,0,0,2"
                    Padding="0,0,0,0"
                    BackgroundColor="{Binding Source={x:Reference CustomView}, Path=FrameColor}"
                    BorderColor="{Binding Source={x:Reference CustomView}, Path=BorderColor}"
                    CornerRadius="{Binding Source={x:Reference CustomView}, Path=CornerRadius}"
                    HasShadow="False"
                    HorizontalOptions="FillAndExpand">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>


                        <ImageButton
                            Grid.Column="0"
                            Margin="5,0,0,0"
                            BackgroundColor="Transparent"
                            Clicked="Button_Clicked"
                            HeightRequest="25"
                            Source="{Binding Source={x:Reference CustomView}, Path=LeftSideIcon}" />


                        <Entry
                            x:Name="EntryControl"
                            Grid.Column="1"
                            Margin="0,0,55,0"
                            HeightRequest="25"
                            HorizontalOptions="FillAndExpand"
                            Keyboard="Chat"
                            Placeholder="{Binding Source={x:Reference CustomView}, Path=Placeholder}"
                            Text="{Binding EntryText}"
                            TextColor="{Binding Source={x:Reference CustomView}, Path=EntryTextColor}" />

                        <ImageButton
                            Grid.Column="1"
                            Margin="0,0,40,0"
                            BackgroundColor="Transparent"
                            Command="{Binding Source={x:Reference CustomView}, Path=DeleteMsgCommand}"
                            HeightRequest="25"
                            HorizontalOptions="End"
                            Source="{Binding Source={x:Reference CustomView}, Path=DeleteMessageIcon}" />

                        <ImageButton
                            Grid.Column="1"
                            Margin="0,0,10,0"
                            Padding="1"
                            BackgroundColor="Transparent"
                            Command="{Binding Source={x:Reference CustomView}, Path=InsertImgCommand}"
                            HeightRequest="25"
                            HorizontalOptions="End"
                            Source="{Binding Source={x:Reference CustomView}, Path=InsertImgIcon}" />


                    </Grid>
                </Frame>

                <ImageButton
                    Margin="0,0,5,2"
                    Padding="15,0,10,0"
                    BackgroundColor="{Binding Source={x:Reference CustomView}, Path=SendBtnColor}"
                    Command="{Binding Source={x:Reference CustomView}, Path=SendMsgCommand}"
                    CornerRadius="30"
                    HeightRequest="45"
                    HorizontalOptions="End"
                    Source="{Binding Source={x:Reference CustomView}, Path=RightSideIcon}"
                    WidthRequest="45" />

            </StackLayout>

            <!--  ================This is what it moves up================  -->
            <StackLayout
                x:Name="frameemojis"
                AbsoluteLayout.LayoutBounds="0,1,1,0.43"
                AbsoluteLayout.LayoutFlags="All"
                TranslationY="{Binding Height, Source={x:Reference frameemojis}}">


                <Frame>


                    <CollectionView
                        Margin="-10,-15,-10,-10"
                        HeightRequest="270"
                        ItemsSource="{Binding Source={x:Reference CustomView}, Path=EmojiItemSource}"
                        VerticalScrollBarVisibility="Never">

                        <CollectionView.ItemsLayout>
                            <GridItemsLayout Orientation="Horizontal" Span="5" />
                        </CollectionView.ItemsLayout>
                        <CollectionView.ItemTemplate>

                            <DataTemplate>

                                <ImageButton
                                    Padding="5"
                                    BackgroundColor="Transparent"
                                    Command="{Binding Source={x:Reference CustomView}, Path=EmojiTappedCommand}"
                                    CommandParameter="{Binding EmojiMethodCommand}"
                                    HeightRequest="44"
                                    Source="{Binding EmojiSource}"
                                    WidthRequest="44" />
                            </DataTemplate>
                        </CollectionView.ItemTemplate>

                    </CollectionView>
                </Frame>
                <!--  ==============  -->
            </StackLayout>


        </StackLayout>



    </AbsoluteLayout>

</ContentView>

Вот как я хочу это сделать

Ответы

LucasZhang-MSFT Nov 09 2020 at 11:59

В ContentPage, потому что вы устанавливаете высоту Stacklayout как весь экран

AbsoluteLayout.LayoutBounds="0,1,1,1" 

Так что это будет ожидаемый результат.

Собственно, в вашем случае вы могли бы реализовать эффект без использования ScrollView.

в ContentPage

<AbsoluteLayout BackgroundColor="White" AbsoluteLayout.LayoutBounds="0,1,1,1">
        <!--  -->

        <Button Clicked="Button_Clicked" Text="Test"  AbsoluteLayout.LayoutBounds="0.5,0.3,0.2,0.05" AbsoluteLayout.LayoutFlags="All" />

        <StackLayout x:Name="bottomBar" BackgroundColor="Olive" AbsoluteLayout.LayoutBounds="0.5,1.0,1.0,0.04" AbsoluteLayout.LayoutFlags="All">
            

            <!-- put the content of emoji keyboard and entry here -->

        </StackLayout>
    </AbsoluteLayout>

В коде позади

    bool isShow;
    const double layoutPropHeightMax = 0.45;
    const double layoutPropHeightMin = 0.06;
   //you could set the height here as you want

    private void Button_Clicked(object sender, EventArgs e)
    {
        if(!isShow)
        {
            //show the keyboard

            Device.BeginInvokeOnMainThread(async () =>
            {

                var height = layoutPropHeightMin;

                while (height < layoutPropHeightMax)
                {
                    await Task.Delay(1);
                    height += 0.04;

                    AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0,1.0, height));
                }

            });

        }

        else
        {
            // hide the keyboard
            Device.BeginInvokeOnMainThread(async () =>
            {

                var height = layoutPropHeightMax;

                while (height > layoutPropHeightMin)
                {
                    await Task.Delay(1);
                    height -= 0.04;

                    AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
                }

            });

        }


        isShow = !isShow;
    }

А в Custom Control пусть Entry и Keyboard заполнят весь StackLayout.