首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态添加StackLayout

动态添加StackLayout
EN

Stack Overflow用户
提问于 2022-05-03 17:27:12
回答 1查看 162关注 0票数 -1

所以我想要做的是有一个堆栈布局,在代码中设置条目时添加条目等等。例如,我有3个条目,一旦它们都被填充,我希望添加一组3个新条目。如果它们被清空,条目就会消失。我还没有完成我的代码来使它工作,因为我被困在了一个非常关键的步骤。

我不知道如何添加已经创建的StackLayout:

代码语言:javascript
复制
        <StackLayout Orientation="Horizontal" x:Name="ingredientsLayout">
            <Entry x:Name="recipeIngredient"
           Placeholder="Ingredient"
           HorizontalOptions="FillAndExpand"
           Margin="20,0,0,0"
           Unfocused="StackLayout_Unfocused"/>
            <dxe1:ComboBoxEdit x:Name="recipeIngredientAmountPicker" 
            LabelText="Amount"
            Margin="10,0,10,0"
            Unfocused="StackLayout_Unfocused"/>
            <Picker x:Name="recipeIngredientMeasurePicker" 
            Title="Measure"
            HorizontalOptions="End"
            Margin="0,0,20,0"
            Unfocused="StackLayout_Unfocused"/>
        </StackLayout>

作为一个新的StackLayout。显然,它并不像添加这一行那样简单: mainStack.Children.Add(ingredientsLayout);

那么我该怎么做呢:)?

编辑:

代码语言:javascript
复制
using Plugin.Media;
using Plugin.Media.Abstractions;
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Food_Recipe_App.Assets.Classes;
using System.Reflection.Metadata;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Collections.ObjectModel;

namespace Food_Recipe_App
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class NewRecipePage : ContentPage
    {
        public StackLayout ingredientsLayoutTemplate = new StackLayout
        {

            Parent = mainStackLayout,
            Orientation = StackOrientation.Horizontal
        };

        Entry ingredientEntry = new Entry { Placeholder = "Ingredient", HorizontalOptions = LayoutOptions.FillAndExpand, Margin = new Thickness(20, 0, 20, 0) };
        Button ingredientAddButton = new Button { Text="+", WidthRequest = 50, HorizontalOptions = LayoutOptions.End, Margin = new Thickness(0,0,20,0) };
        Button ingredientRemoveButton = new Button { Text = "-", WidthRequest = 50, HorizontalOptions = LayoutOptions.End, Margin = new Thickness(0, 0, 20, 0), IsVisible = false };

        public List<StackLayout> ingredientsStackLayouts = new List<StackLayout>();
        public List<Entry> ingredientsEntries = new List<Entry>();
        public List<Button> ingredientsAddButtons = new List<Button>();
        public List<Button> ingredientsRemoveButtons = new List<Button>();

        public bool newStackAdded = false;

        public static string nullString = "none";

        public static StackLayout mainStackLayout;

        public NewRecipePage()
        {
            InitializeComponent();

            var assembly = typeof(NewRecipePage);

            recipeImage.Source = ImageSource.FromResource("Food_Recipe_App.Assets.Images.MainPage.crypto_ball.png", assembly);

            var measureList = Food_Recipe_App.Assets.Classes.Ingrediens.Measure;

            //recipeIngredientMeasurePicker.ItemsSource = measureList;
            //recipeIngredientAmountPicker.ItemsSource = Ingrediens.MeasureCount;

            ingredientAddButton.Clicked += recipeAddIngredient_Clicked;
            ingredientRemoveButton.Clicked += recipeRemoveIngredient_Clicked;

            ingredientsStackLayouts.Clear();
            ingredientsEntries.Clear();
            ingredientsAddButtons.Clear();
            ingredientsRemoveButtons.Clear();

            ingredientsStackLayouts.Add(this.ingredientsLayout);
            ingredientsEntries.Add(this.recipeIngredient);
            ingredientsAddButtons.Add(this.recipeAddIngredient);
            ingredientsRemoveButtons.Add(this.recipeRemoveIngredient);

            mainStackLayout = mainStack;
        }

        private void saveRecipe_Clicked(object sender, EventArgs e)
        {
            Recipe recipe = new Recipe()
            {
                title = recipeTitle.Text,
                description = recipeDesc.Text,
                //image = recipeImage
            };
            using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
            {
                conn.CreateTable<Recipe>();
                int rows = conn.Insert(recipe);

                if (rows > 0)
                {
                    DisplayAlert("Success", "Recipe successfully added", "Ok");
                }
                else
                {
                    DisplayAlert("Failure", "Recipe not added, try again", "Ok");
                }
            };

            Navigation.PopAsync();
        }

        async void recipeImage_Clicked(object sender, EventArgs e)
        {
            await CrossMedia.Current.Initialize();

            if (!CrossMedia.Current.IsPickPhotoSupported)
            {
                await DisplayAlert("Not supported", "Your device does not currently support this functionality", "Ok");
                return;
            }

            var mediaOptions = new PickMediaOptions()
            {
                PhotoSize = PhotoSize.Medium
            };

            var recipeImageFile = await CrossMedia.Current.PickPhotoAsync(mediaOptions);

            if (recipeImageFile == null)
            {
                await DisplayAlert("Error", "Could not get the image, please try again", "Ok");
                return;
            }
            else
            {
                recipeImage.Source = ImageSource.FromStream(() => recipeImageFile.GetStream());
            }
        }

        private void recipeAddIngredient_Clicked(object sender, EventArgs e)
        {
            recipeAddIngredientTemplate();

            //recipeAddIngredient.IsVisible = false;

            //recipeRemoveIngredient.IsVisible = true;
        }

        private void recipeRemoveIngredient_Clicked(object sender, EventArgs e)
        {
            recipeRemoveIngredient.IsVisible = false;

            recipeAddIngredient.IsVisible = true;

            //mainStack.Children.Remove(recipeIngredient.Parent as View);

            //mainStack.Children.Remove(ingredientsStackLayouts[ingredientsStackLayouts.Count - 1]);

            //ingredientsStackLayouts.Remove(ingredientsStackLayouts[ingredientsStackLayouts.Count - 1]);

            //ingredientsStackLayouts[ingredientsStackLayouts.Count - 1].IsVisible = false;
        }

        public void recipeAddIngredientTemplate()
        {
            ingredientsStackLayouts.Add(ingredientsLayoutTemplate);
            ingredientsEntries.Add(ingredientEntry);
            ingredientsAddButtons.Add(ingredientAddButton);
            ingredientsRemoveButtons.Add(ingredientRemoveButton);

            ingredientsStackLayouts[ingredientsStackLayouts.Count - 1].Children.Add(ingredientsEntries[ingredientsEntries.Count - 1]);
            ingredientsStackLayouts[ingredientsStackLayouts.Count - 1].Children.Add(ingredientsAddButtons[ingredientsAddButtons.Count - 1]);
            ingredientsStackLayouts[ingredientsStackLayouts.Count - 1].Children.Add(ingredientsRemoveButtons[ingredientsRemoveButtons.Count - 1]);

            mainStack.Children.Add(ingredientsStackLayouts[ingredientsStackLayouts.Count - 1]);
        }
    }
}
代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:dxe1="http://schemas.devexpress.com/xamarin/2014/forms/editors"
             x:Class="Food_Recipe_App.NewRecipePage">
    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="saveRecipe" Text="Save Recipe"
                     Clicked="saveRecipe_Clicked"/>
    </ContentPage.ToolbarItems>

    <ContentPage.Content>
        <StackLayout x:Name="mainStack">
            <Entry x:Name="recipeTitle"
               Placeholder="Name"/>
            <Entry x:Name="recipeDesc"
               Placeholder="Description"/>
            <Image x:Name="recipeImage"/>
            <Button x:Name="recipeImageAddButton"
                Clicked="recipeImage_Clicked"
                Text="Upload Image"/>
            <Label x:Name="ingredientTitle"
               Text="Ingredients"
               HorizontalOptions="CenterAndExpand"
               FontAttributes="Bold"/>
            <StackLayout Orientation="Horizontal" x:Name="ingredientsLayout">
                <Entry x:Name="recipeIngredient"
               Placeholder="Ingredient"
               HorizontalOptions="FillAndExpand"
               Margin="20,0,20,0"/>
                <Button x:Name="recipeAddIngredient"
                        Text="+"
                        WidthRequest="50"
                        HorizontalOptions="End"
                        Margin="0,0,20,0"
                        Clicked="recipeAddIngredient_Clicked"/>
                <Button x:Name="recipeRemoveIngredient"
                        Text="-"
                        WidthRequest="50"
                        HorizontalOptions="End"
                        Margin="0,0,20,0"
                        Clicked="recipeRemoveIngredient_Clicked"
                        IsVisible="false"/>
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>

</ContentPage>
EN

回答 1

Stack Overflow用户

发布于 2022-05-05 01:55:04

首先,根据您的描述,您希望在不同的位置使用相同的布局。所以你可以试试这两种解决方案。

  1. 创建一个新变量,即StackLayout类型,并将子视图添加到布局中。之后,你可以在任何地方使用它。例如:

StackLayout layout = new StackLayout(); layout.Children.Add(new Label...);

您可以通过mainstack1.Children.Remove(layout);mainstack1.Children.Add(layout);添加和删除它。

  1. 使用ContentView来包含StackLayout。然后,您可以在xaml中的任何地方使用内容视图。但是,如果在xaml中使用视图,则该视图似乎无法重构。您可以通过IsVisible属性使其不可见。

此外,您还可以在contentview中获取堆栈布局,并通过layout.Children.Clear()清除它。然后是一个空白的contentview.

编辑:这是因为按钮事件在您声明的页面中。换句话说,它在其他地方没有绑定上下文。这样就可以将StackLayout放入静态类中。例如:

代码语言:javascript
复制
public static class LayoutTest
{
    public static StackLayout stack;
}

然后在第一个使用该控件的页面上设置控件:

代码语言:javascript
复制
   public AboutPage()
    {
        InitializeComponent();
        LayoutTest.stack = new StackLayout();
        Button button = new Button() { Text = "Click Me" };
        button.Clicked += (s, e) =>
        {
            Console.WriteLine("-----------------------------------");
        };
        LayoutTest.stack.Children.Add(button);
        about.Children.Add(LayoutTest.stack);
    }

然后,您可以在任何地方使用它,例如:

代码语言:javascript
复制
public ItemDetailPage()
    {
        InitializeComponent();
        BindingContext = new ItemDetailViewModel();
        mainstack.Children.Add(LayoutTest.stack);
    }

此外,还可以将单击事件添加到使用堆栈布局的每个页面。但这是重复的工作。

最后,内容视图是最好的选择,因为它有xaml和.cs文件,所以它有自己的绑定上下文。

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

https://stackoverflow.com/questions/72103241

复制
相关文章

相似问题

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