【问题标题】:How do implement panel feature in Xamarin.forms如何在 Xamarin.forms 中实现面板功能
【发布时间】:2016-08-05 13:42:19
【问题描述】:

就像在 Windows 窗体中一样,我们可以在同一个窗体中添加多个面板,并根据某些条件显示和隐藏特定面板。 Xamarin.Forms里面有没有可以这样使用的控件?

这背后的主要原因是,我在一个页面上有 3 个标签。我使用选项卡按钮而不是选项卡页面,因为选项卡栏的设计不是我的客户想要的。所以我有 3 个页面,比如 Page APage BPage C,每个页面都有 3 个选项卡可以转到相应的页面。如果用户在Page A 并填写某种数据(尚未保存)并想转到Page B 然后在Page B 他填写更多详细信息然后在Page B 上不保存数据他回到Page A,用户在Page APage B 上填写的所有详细信息都必须可用。

因此,如果我为此使用多个页面,那么当我重定向到新页面时数据将丢失。那么有什么方法可以让我有多个面板并在第二个面板可见时隐藏第一个面板,这不会清除任何数据,因此我可以实现我想要的。

【问题讨论】:

    标签: c# xamarin navigation xamarin.forms


    【解决方案1】:

    您可以只隐藏未使用的面板(使用 IsVisible 属性) - 这会将它们从可视化树中拉出,但不会从内存中释放它们。

    如果您为每个页面创建一个内容视图,那么您可以轻松地在主 UI 中使用它们,例如在本示例中。即使我们隐藏了各个面板,它们在隐藏时仍会保留在内存中:

    MyView.cs(这可以是您面板中的任何内容):

    using System;
    using Xamarin.Forms;
    
    namespace FormsSandbox
    {
        public class MyView : ContentView
        {
            public static BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(MyView), 
                String.Empty, BindingMode.Default, null, TextChanged);
    
            public string Text {
                get {
                    return (string)GetValue (TextProperty);
                }
                set {
                    SetValue (TextProperty, value);
                }
            }
    
            private Label _contentLabel;
    
            public MyView ()
            {
                _contentLabel = new Label {
                    FontSize = 56,
                    FontAttributes = FontAttributes.Bold,
                    HorizontalTextAlignment = TextAlignment.Center,
                    VerticalTextAlignment = TextAlignment.Center
                };
                Content = _contentLabel;
            }
    
            static void TextChanged (BindableObject bindable, object oldValue, object newValue)
            {
                var view = (MyView)bindable;
                view._contentLabel.Text = (newValue ?? "").ToString ();
            }
        }
    }
    

    XamlPage.xaml(主 UI 页面):

    <?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:sandbox="clr-namespace:FormsSandbox"
        x:Class="FormsSandbox.XamlPage">
        <ContentPage.Padding>
            <OnPlatform x:TypeArguments="Thickness" iOS="0,20,0,0" Android="0" WinPhone="0"/>
        </ContentPage.Padding>
    
        <Grid RowSpacing="0" ColumnSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
    
            <Button Text="1" Clicked="ButtonClicked" x:Name="Button1" Grid.Column="0" />
            <Button Text="2" Clicked="ButtonClicked" x:Name="Button2" Grid.Column="1" />
            <Button Text="3" Clicked="ButtonClicked" x:Name="Button3" Grid.Column="2" />
    
            <sandbox:MyView Text="1" x:Name="View1" Grid.Row="1" Grid.ColumnSpan="3" />
            <sandbox:MyView Text="2" x:Name="View2" Grid.Row="1" Grid.ColumnSpan="3" />
            <sandbox:MyView Text="3" x:Name="View3" Grid.Row="1" Grid.ColumnSpan="3" />
        </Grid>
    
    </ContentPage>
    

    XamlPage.xaml.cs:

    using System;
    using Xamarin.Forms;
    
    namespace FormsSandbox
    {
        public partial class XamlPage : ContentPage
        {
            public XamlPage ()
            {
                InitializeComponent ();
                SelectButton (Button1);
            }
    
            void SelectButton(Button button)
            {
                View view = null;
                if (button == Button1)
                    view = View1;
                if (button == Button2)
                    view = View2;
                if (button == Button3)
                    view = View3;
                View1.IsVisible = View1 == view;
                View2.IsVisible = View2 == view;
                View3.IsVisible = View3 == view;
                Button1.TextColor = (Button1 == button) ? Color.Accent.AddLuminosity(0.18) : (Color)Button.TextColorProperty.DefaultValue;
                Button2.TextColor = (Button2 == button) ? Color.Accent.AddLuminosity(0.18) : (Color)Button.TextColorProperty.DefaultValue;
                Button3.TextColor = (Button3 == button) ? Color.Accent.AddLuminosity(0.18) : (Color)Button.TextColorProperty.DefaultValue;
                Button1.BackgroundColor = (Button1 == button) ? Color.Silver.AddLuminosity(0.18) : Color.Silver.AddLuminosity(0.1);
                Button2.BackgroundColor = (Button2 == button) ? Color.Silver.AddLuminosity(0.18) : Color.Silver.AddLuminosity(0.1);
                Button3.BackgroundColor = (Button3 == button) ? Color.Silver.AddLuminosity(0.18) : Color.Silver.AddLuminosity(0.1);
            }
    
            void ButtonClicked (object sender, EventArgs e)
            {
                SelectButton ((Button)sender);
            }
        }
    }
    

    【讨论】:

    • 你能看看question。我无法访问我的 contentPage 中的 contentview 输入字段
    • 我也看了那个问题,并添加了一个应该有帮助的答案。如果它对您有用,请标记为答案,这样其他人就不会花时间尝试解决您不再遇到的问题:)。
    【解决方案2】:

    您可以将此数据保存到缓存中并从那里加载。

    public static class MyDataCache 
    {
        public static MyData MyData { get; } = new MyData();
    }
    
    // in your pages
    protected override void OnAppearing()
    {            
        base.OnAppearing();
        // set data from MyDataCache.MyData
        MyProperty = MyDataCache.MyData.MyProperty;
    }
    
    protected override void OnDisappearing()
    {            
        base.OnDisappearing();
        // set data to MyDataCache.MyData
        MyDataCache.MyData.MyProperty = MyProperty;
    }
    

    但请注意:它只是一个内存缓存。如果应用程序被墓碑化,数据将会丢失。您可以先尝试这种方法,看看它是否适合您的需要。之后,您应该将数据存储在临时存储中(例如使用Akavache)。您不应该使用自定义的东西来重建此页面导航行为。

    【讨论】:

    • 通过将其保存到缓存中,这些值仍然会在页面更改时保持不变?
    • 是的。它是一个静态类。只要应用程序在内存中,它就在内存中。你只需要在页面出现时填写你的属性。
    • 只是为了确认,在加载页面时说 Page A 我正在从 xml 文件中读取数据,对其进行序列化并将其显示在文本框和其他控件中,当用户转到 Page B 时,它将调用 onDisappearing并将数据保存在静态变量中。然后,当我从 Page B 返回到 Page A 时,我将不得不再次使用静态变量中保存的数据填充我的控件?
    • 我已经在页面的构造函数中编写了读取 xml 文件和填充控件的代码,我将不得不移动到 onAppear?
    • 是的,我想是的 :)
    【解决方案3】:

    只需使用框架:

    <StackLayout>
        <Frame x:Name="MyPanelABC">
            <Label Text="My Stuff" />
        </Frame>
    </StackLayout>
    
    private void setupPanelABC(bool isVisiblePanelABC){
        MyPanelABC.IsVisible = isVisiblePanelABC;
    }
    

    【讨论】:

    • 虽然此代码 sn-p 可能会解决问题,但including an explanation 将帮助人们了解您的代码建议的原因。
    猜你喜欢
    • 2015-12-16
    • 1970-01-01
    • 2021-09-06
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多