คุณเปลี่ยนหน้าใน Xamarin.Forms ได้อย่างไร?


102

คุณสลับไปมาระหว่างหน้าต่างๆใน Xamarin Forms ได้อย่างไร?

หน้าหลักของฉันคือ ContentPage และฉันไม่ต้องการเปลี่ยนไปใช้หน้าแบบแท็บ

ฉันสามารถหลอกได้โดยการค้นหาผู้ปกครองของการควบคุมที่ควรทริกเกอร์หน้าใหม่จนกว่าฉันจะพบ ContentPage จากนั้นสลับเนื้อหาด้วยการควบคุมสำหรับเพจใหม่ แต่ดูเหมือนว่าจะเลอะเทอะจริงๆ


มีคำตอบมากมายสำหรับคำถามนี้แล้วหากต้องการดูว่าสามารถทำได้โดยใช้รูปแบบโครงสร้าง MVVM โปรดดูที่stackoverflow.com/a/37142513/9403963
Alireza Sattari

คำตอบ:


68

Xamarin.Forms รองรับโฮสต์การนำทางหลายตัวในตัว:

  • NavigationPageที่หน้าถัดไปเลื่อนเข้า
  • TabbedPageคนที่คุณไม่ชอบ
  • CarouselPageซึ่งช่วยให้สามารถสลับซ้ายและขวาไปยังหน้าถัดไป / ก่อนหน้า

นอกจากนี้ทุกหน้ายังรองรับPushModalAsync()ซึ่งเพียงแค่ดันหน้าใหม่ไว้ด้านบนของหน้าที่มีอยู่

ในตอนท้ายหากคุณต้องการให้แน่ใจว่าผู้ใช้ไม่สามารถกลับไปที่หน้าก่อนหน้านี้ได้ (โดยใช้ท่าทางสัมผัสหรือปุ่มฮาร์ดแวร์ด้านหลัง) คุณสามารถPageแสดงสิ่งเดิมและแทนที่Contentได้

ตัวเลือกที่แนะนำในการเปลี่ยนหน้ารูทก็ใช้ได้เช่นกัน แต่คุณจะต้องจัดการสิ่งนั้นแตกต่างกันไปสำหรับแต่ละแพลตฟอร์ม


PushModalAsync น่าจะเป็นส่วนหนึ่งของการนำทางใช่ไหม ฉันหาวิธีไปที่วัตถุ / คลาสการนำทางไม่ได้ ฉันคิดว่าฉันจำเป็นต้องเข้าถึงบางอย่างที่ใช้ INavigation แต่อะไรล่ะ?
Eric

หากเพจของคุณอยู่ใน NavigationPage คุณควรจะสามารถเข้าถึงคุณสมบัติการนำทางจากภายในเพจของคุณ
Jason

1
เมื่อฉันเริ่มใช้ NavigationPage ทุกอย่างก็เข้าที่ ขอบคุณ
Eric

1
@stephane โปรดบอกว่าหน้าแรกของฉันคือ CarouselPage และหน้าที่สองของฉันคือ masterDetailPage แล้วฉันจะเปลี่ยนหน้าได้อย่างไร stackoverflow.com/questions/31129845/…
Atul Dhanuka

64

ในคลาส App คุณสามารถตั้งค่า MainPage เป็นเพจนำทางและตั้งค่าเพจรูทเป็น ContentPage ของคุณ:

public App ()
{
    // The root page of your application
    MainPage = new NavigationPage( new FirstContentPage() );
}

จากนั้นในการเรียก ContentPage ครั้งแรกของคุณ:

Navigation.PushAsync (new SecondContentPage ());

ฉันทำอย่างนั้น แต่หน้าหลักยังคงเป็นหน้าเริ่มต้นที่เปิดขึ้น หน้าใด ๆ ที่ฉันตั้งเป็นหน้าหลักก็ไม่มีผล ฉันเพิ่งเปิดหน้าแรกได้ตั้งค่า มีปัญหาอะไร?
Behzad

Visual Studio แนะนำการนำเข้าAndroid.Content.Resสำหรับการนำทาง ดูเหมือนจะไม่ถูกต้องฉันต้องนำเข้าจากไหน
Christian

41

หากโครงการของคุณได้รับการตั้งค่าเป็นโครงการแบบฟอร์ม PCL (และมีแนวโน้มว่าจะเป็นแบบฟอร์มที่ใช้ร่วมกันด้วย แต่ฉันยังไม่ได้ลอง) จะมีคลาส App.cs ที่มีลักษณะดังนี้:

public class App
{
    public static Page GetMainPage ()
    {     
        AuditorDB.Model.Extensions.AutoTimestamp = true;
        return new NavigationPage (new LoginPage ());
    }
}

คุณสามารถแก้ไขGetMainPageวิธีการเพื่อส่งคืน TabbedPaged ใหม่หรือเพจอื่น ๆ ที่คุณกำหนดไว้ในโปรเจ็กต์

จากตรงนั้นคุณสามารถเพิ่มคำสั่งหรือตัวจัดการเหตุการณ์เพื่อรันโค้ดและทำ

// to show OtherPage and be able to go back
Navigation.PushAsync(new OtherPage());

// to show AnotherPage and not have a Back button
Navigation.PushModalAsync(new AnotherPage()); 

// to go back one step on the navigation stack
Navigation.PopAsync();

3
สิ่งนี้ไม่ได้สลับไปมาระหว่างหน้า สิ่งนี้จะเปลี่ยนเฉพาะหน้าที่โหลดในตอนแรก
dakamojo

คำถามของคุณกำลังพูดถึงหน้าหลัก ดูคำตอบที่อัปเดตสำหรับตัวอย่างการนำทาง
Sten Petrov

ห่าเป็นNavigationในตัวอย่างนี้? - นั่นคือวัตถุที่คุณสร้างขึ้นที่ไหนสักแห่ง? - ฉันไม่เห็นในตัวอย่างโค้ดนี้
BrainSlugs83

การนำทางเป็นทรัพย์สินบนเพจ
Sten Petrov

ขอบคุณ; FTR PushAsync()ไม่ทำงานสำหรับฉันในขณะที่PushModalAsync()ไม่ได้ทำ
knocte

23

ดันหน้าใหม่ลงบนสแต็กจากนั้นลบเพจปัจจุบัน ส่งผลให้เกิดการสลับ

item.Tapped += async (sender, e) => {
    await Navigation.PushAsync (new SecondPage ());
    Navigation.RemovePage(this);
};

คุณต้องอยู่ในหน้าการนำทางก่อน:

MainPage = NavigationPage(new FirstPage());

การสลับเนื้อหาไม่เหมาะอย่างยิ่งเนื่องจากคุณมีเพจขนาดใหญ่เพียงเพจเดียวและชุดเหตุการณ์ในเพจเช่น OnAppearing ect


Navigation.RemovePage();ไม่รองรับบน Android
Rohit Vipin Mathews

1
Navigation.RemovePage (หน้า); ทำงานใน Android ต้องอยู่ในหน้าการนำทางก่อน
Daniel Roberts

ฉันใช้มันอย่างกว้างขวางในโครงการของฉันในแบบฟอร์ม 1.4.2 บางทีพวกเขาแก้ไขข้อบกพร่องหรือฉันโชคดีที่ยังไม่โดน
Daniel Roberts

ฉันใช้เวอร์ชันล่าสุดและสามารถทำซ้ำได้ ดังนั้นฉันเชื่อว่าคุณโชคดีเกินไป
Rohit Vipin Mathews

2
คำใบ้ที่มีประโยชน์ - หากต้องการลบการเปลี่ยนเมื่อเปลี่ยนหน้าให้เพิ่มเท็จเป็นพารามิเตอร์ที่สอง:await Navigation.PushAsync(new SecondPage(),false);
เดเมียนกรีน

8

หากคุณไม่ต้องการไปที่หน้าที่แล้วเช่นอย่าปล่อยให้ผู้ใช้กลับไปที่หน้าจอล็อกอินเมื่อทำการอนุญาตเสร็จแล้วคุณสามารถใช้;

 App.Current.MainPage = new HomePage();

หากคุณต้องการเปิดใช้งานฟังก์ชันย้อนกลับให้ใช้ไฟล์

Navigation.PushModalAsync(new HomePage())

4

ด้วยการใช้เมธอด PushAsync () คุณสามารถพุชและ PopModalAsync () คุณสามารถป๊อปเพจเข้าและออกจากสแตกการนำทางได้ ในตัวอย่างโค้ดของฉันด้านล่างฉันมีหน้าการนำทาง (หน้ารูท) และจากหน้านี้ฉันดันหน้าเนื้อหาที่เป็นหน้าเข้าสู่ระบบเมื่อฉันกรอกหน้าเข้าสู่ระบบเสร็จแล้วฉันจะกลับไปที่หน้ารูท

~~~ การนำทางสามารถคิดได้ว่าเป็นสแต็กสุดท้ายในลำดับแรกของวัตถุในหน้าหากต้องการย้ายจากหน้าหนึ่งไปยังอีกหน้าหนึ่งแอปพลิเคชันจะผลักหน้าใหม่ไปยังกองนี้ หากต้องการย้อนกลับไปยังหน้าก่อนหน้านี้แอปพลิเคชันจะแสดงหน้าปัจจุบันจากสแตก การนำทางใน Xamarin.Forms นี้จัดการโดยอินเทอร์เฟซ INavigation

Xamarin.Forms มีคลาส NavigationPage ที่ใช้อินเทอร์เฟซนี้และจะจัดการสแต็กของ Pages คลาส NavigationPage จะเพิ่มแถบการนำทางที่ด้านบนของหน้าจอที่แสดงชื่อเรื่องและจะมีปุ่มย้อนกลับที่เหมาะสมกับแพลตฟอร์มซึ่งจะกลับไปยังหน้าก่อนหน้า รหัสต่อไปนี้แสดงวิธีการรวม NavigationPage รอบ ๆ หน้าแรกในแอปพลิเคชัน:

การอ้างอิงถึงเนื้อหาข้างต้นและลิงก์ที่คุณควรตรวจสอบสำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Xamarin Forms โปรดดูส่วนการนำทาง:

http://developer.xamarin.com/guides/cross-platform/xamarin-forms/introduction-to-xamarin-forms/

~~~

public class MainActivity : AndroidActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        Xamarin.Forms.Forms.Init(this, bundle);
        // Set our view from the "main" layout resource
        SetPage(BuildView());
    }

    static Page BuildView()
    {
        var mainNav = new NavigationPage(new RootPage());
        return mainNav;
    }
}


public class RootPage : ContentPage
{
    async void ShowLoginDialog()
    {
        var page = new LoginPage();

        await Navigation.PushModalAsync(page);
    }
}

// ลบโค้ดเพื่อความเรียบง่ายเฉพาะป๊อปเท่านั้นที่แสดงขึ้น

private async void AuthenticationResult(bool isValid)
{
    await navigation.PopModalAsync();
}

4

ดูเหมือนว่าหัวข้อนี้เป็นที่นิยมมากและมันจะเป็นเรื่องน่าเศร้าที่จะไม่พูดถึงที่นี่ว่ามีทางเลือก ViewModel First Navigation- เฟรมเวิร์ก MVVM ส่วนใหญ่ใช้อยู่อย่างไรก็ตามหากคุณต้องการเข้าใจว่ามันเกี่ยวกับอะไรให้อ่านต่อ

เอกสาร Xamarin.Forms อย่างเป็นทางการทั้งหมดแสดงให้เห็นถึงโซลูชันที่เรียบง่าย แต่ไม่ใช่วิธีการแก้ปัญหาบริสุทธิ์ของ MVVM เล็กน้อย นั่นเป็นเพราะPage(View) ไม่ควรรู้อะไรเกี่ยวกับViewModelและในทางกลับกัน นี่คือตัวอย่างที่ดีของการละเมิดนี้:

// C# version
public partial class MyPage : ContentPage
{
    public MyPage()
    {
        InitializeComponent();
        // Violation
        this.BindingContext = new MyViewModel();
    }
}

// XAML version
<?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:viewmodels="clr-namespace:MyApp.ViewModel"
    x:Class="MyApp.Views.MyPage">
    <ContentPage.BindingContext>
        <!-- Violation -->
        <viewmodels:MyViewModel />
    </ContentPage.BindingContext>
</ContentPage>

หากคุณมีแอปพลิเคชัน 2 หน้าวิธีนี้อาจดีสำหรับคุณ อย่างไรก็ตามหากคุณกำลังทำงานกับโซลูชันระดับองค์กรขนาดใหญ่คุณควรใช้ViewModel First Navigationแนวทางนี้ มีความซับซ้อนกว่าเล็กน้อย แต่เป็นวิธีที่สะอาดกว่ามากซึ่งช่วยให้คุณสามารถนำทางไปมาระหว่างViewModelsการนำทางระหว่างPages(มุมมอง) ข้อดีอย่างหนึ่งนอกเหนือจากการแยกข้อกังวลที่ชัดเจนคือคุณสามารถส่งผ่านพารามิเตอร์ไปยังหัวข้อถัดไปViewModelหรือเรียกใช้รหัสเริ่มต้น async ได้ทันทีหลังจากการนำทาง ตอนนี้เพื่อดูรายละเอียด

(ฉันจะพยายามลดความซับซ้อนของตัวอย่างโค้ดทั้งหมดให้มากที่สุด)

1. ก่อนอื่นเราต้องมีสถานที่ที่เราสามารถลงทะเบียนวัตถุทั้งหมดของเราและกำหนดอายุการใช้งานได้ สำหรับเรื่องนี้เราสามารถใช้คอนเทนเนอร์ IOC คุณสามารถเลือกได้ด้วยตัวเอง ในตัวอย่างนี้ฉันจะใช้Autofac (เป็นหนึ่งในโปรแกรมที่เร็วที่สุด) เราสามารถเก็บข้อมูลอ้างอิงไว้Appเพื่อให้สามารถใช้งานได้ทั่วโลก (ไม่ใช่ความคิดที่ดี แต่จำเป็นสำหรับการทำให้เข้าใจง่าย):

public class DependencyResolver
{
    static IContainer container;

    public DependencyResolver(params Module[] modules)
    {
        var builder = new ContainerBuilder();

        if (modules != null)
            foreach (var module in modules)
                builder.RegisterModule(module);

        container = builder.Build();
    }

    public T Resolve<T>() => container.Resolve<T>();
    public object Resolve(Type type) => container.Resolve(type);
}

public partial class App : Application
{
    public DependencyResolver DependencyResolver { get; }

    // Pass here platform specific dependencies
    public App(Module platformIocModule)
    {
        InitializeComponent();
        DependencyResolver = new DependencyResolver(platformIocModule, new IocModule());
        MainPage = new WelcomeView();
    }

    /* The rest of the code ... */
}

2. เราจะต้องมีวัตถุที่รับผิดชอบในการดึงข้อมูลPage(View) สำหรับเฉพาะViewModelและในทางกลับกัน กรณีที่สองอาจมีประโยชน์ในกรณีของการตั้งค่ารูท / หน้าหลักของแอพ ด้วยเหตุนี้เราควรเห็นด้วยกับหลักการง่ายๆว่าViewModelsควรอยู่ในViewModelsไดเรกทอรีและPages(มุมมอง) ควรอยู่ในViewsไดเรกทอรี กล่าวอีกนัยหนึ่งViewModelsควรอยู่ใน[MyApp].ViewModelsเนมสเปซและPages(มุมมอง) ใน[MyApp].Viewsเนมสเปซ นอกจากนั้นเราควรยอมรับว่าWelcomeView(หน้า) ควรมีWelcomeViewModelและอื่น ๆ นี่คือตัวอย่างโค้ดของผู้ทำแผนที่:

public class TypeMapperService
{
    public Type MapViewModelToView(Type viewModelType)
    {
        var viewName = viewModelType.FullName.Replace("Model", string.Empty);
        var viewAssemblyName = GetTypeAssemblyName(viewModelType);
        var viewTypeName = GenerateTypeName("{0}, {1}", viewName, viewAssemblyName);
        return Type.GetType(viewTypeName);
    }

    public Type MapViewToViewModel(Type viewType)
    {
        var viewModelName = viewType.FullName.Replace(".Views.", ".ViewModels.");
        var viewModelAssemblyName = GetTypeAssemblyName(viewType);
        var viewTypeModelName = GenerateTypeName("{0}Model, {1}", viewModelName, viewModelAssemblyName);
        return Type.GetType(viewTypeModelName);
    }

    string GetTypeAssemblyName(Type type) => type.GetTypeInfo().Assembly.FullName;
    string GenerateTypeName(string format, string typeName, string assemblyName) =>
        string.Format(CultureInfo.InvariantCulture, format, typeName, assemblyName);
}

3. ในกรณีของการตั้งค่าหน้ารูทเราจะต้องมีการViewModelLocatorตั้งค่าBindingContextโดยอัตโนมัติ:

public static class ViewModelLocator
{
    public static readonly BindableProperty AutoWireViewModelProperty =
        BindableProperty.CreateAttached("AutoWireViewModel", typeof(bool), typeof(ViewModelLocator), default(bool), propertyChanged: OnAutoWireViewModelChanged);

    public static bool GetAutoWireViewModel(BindableObject bindable) =>
        (bool)bindable.GetValue(AutoWireViewModelProperty);

    public static void SetAutoWireViewModel(BindableObject bindable, bool value) =>
        bindable.SetValue(AutoWireViewModelProperty, value);

    static ITypeMapperService mapper = (Application.Current as App).DependencyResolver.Resolve<ITypeMapperService>();

    static void OnAutoWireViewModelChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var view = bindable as Element;
        var viewType = view.GetType();
        var viewModelType = mapper.MapViewToViewModel(viewType);
        var viewModel =  (Application.Current as App).DependencyResolver.Resolve(viewModelType);
        view.BindingContext = viewModel;
    }
}

// Usage example
<?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:viewmodels="clr-namespace:MyApp.ViewModel"
    viewmodels:ViewModelLocator.AutoWireViewModel="true"
    x:Class="MyApp.Views.MyPage">
</ContentPage>

4. ในที่สุดเราจะต้องมีแนวทางNavigationServiceที่จะสนับสนุนViewModel First Navigationแนวทาง:

public class NavigationService
{
    TypeMapperService mapperService { get; }

    public NavigationService(TypeMapperService mapperService)
    {
        this.mapperService = mapperService;
    }

    protected Page CreatePage(Type viewModelType)
    {
        Type pageType = mapperService.MapViewModelToView(viewModelType);
        if (pageType == null)
        {
            throw new Exception($"Cannot locate page type for {viewModelType}");
        }

        return Activator.CreateInstance(pageType) as Page;
    }

    protected Page GetCurrentPage()
    {
        var mainPage = Application.Current.MainPage;

        if (mainPage is MasterDetailPage)
        {
            return ((MasterDetailPage)mainPage).Detail;
        }

        // TabbedPage : MultiPage<Page>
        // CarouselPage : MultiPage<ContentPage>
        if (mainPage is TabbedPage || mainPage is CarouselPage)
        {
            return ((MultiPage<Page>)mainPage).CurrentPage;
        }

        return mainPage;
    }

    public Task PushAsync(Page page, bool animated = true)
    {
        var navigationPage = Application.Current.MainPage as NavigationPage;
        return navigationPage.PushAsync(page, animated);
    }

    public Task PopAsync(bool animated = true)
    {
        var mainPage = Application.Current.MainPage as NavigationPage;
        return mainPage.Navigation.PopAsync(animated);
    }

    public Task PushModalAsync<TViewModel>(object parameter = null, bool animated = true) where TViewModel : BaseViewModel =>
        InternalPushModalAsync(typeof(TViewModel), animated, parameter);

    public Task PopModalAsync(bool animated = true)
    {
        var mainPage = GetCurrentPage();
        if (mainPage != null)
            return mainPage.Navigation.PopModalAsync(animated);

        throw new Exception("Current page is null.");
    }

    async Task InternalPushModalAsync(Type viewModelType, bool animated, object parameter)
    {
        var page = CreatePage(viewModelType);
        var currentNavigationPage = GetCurrentPage();

        if (currentNavigationPage != null)
        {
            await currentNavigationPage.Navigation.PushModalAsync(page, animated);
        }
        else
        {
            throw new Exception("Current page is null.");
        }

        await (page.BindingContext as BaseViewModel).InitializeAsync(parameter);
    }
}

อย่างที่คุณเห็นมีBaseViewModel- คลาสพื้นฐานที่เป็นนามธรรมสำหรับทุกViewModelsที่ที่คุณสามารถกำหนดวิธีการเช่นInitializeAsyncนั้นจะได้รับการดำเนินการทันทีหลังจากการนำทาง และนี่คือตัวอย่างการนำทาง:

public class WelcomeViewModel : BaseViewModel
{
    public ICommand NewGameCmd { get; }
    public ICommand TopScoreCmd { get; }
    public ICommand AboutCmd { get; }

    public WelcomeViewModel(INavigationService navigation) : base(navigation)
    {
        NewGameCmd = new Command(async () => await Navigation.PushModalAsync<GameViewModel>());
        TopScoreCmd = new Command(async () => await navigation.PushModalAsync<TopScoreViewModel>());
        AboutCmd = new Command(async () => await navigation.PushModalAsync<AboutViewModel>());
    }
}

ตามที่คุณเข้าใจว่าแนวทางนี้ซับซ้อนกว่าแก้ไขจุดบกพร่องยากกว่าและอาจทำให้สับสนได้ อย่างไรก็ตามมีข้อดีมากมายและคุณไม่จำเป็นต้องใช้งานด้วยตัวเองเนื่องจากเฟรมเวิร์ก MVVM ส่วนใหญ่รองรับการใช้งานนอกกรอบ ตัวอย่างรหัสที่แสดงให้เห็นที่นี่เป็นที่ที่มีอยู่บนGitHub

มีบทความดีๆมากมายเกี่ยวกับViewModel First Navigationแนวทางและมีรูปแบบแอปพลิเคชันสำหรับองค์กรฟรีโดยใช้ Xamarin.Forms eBook ซึ่งอธิบายเรื่องนี้และหัวข้อที่น่าสนใจอื่น ๆ อีกมากมายโดยละเอียด


2

หนึ่งเพจไปยังอีกเพจหนึ่งใน Xamarin.forms โดยใช้คุณสมบัติการนำทางด้านล่างโค้ดตัวอย่าง

void addClicked(object sender, EventArgs e)
        {
            //var createEmp = (Employee)BindingContext;
            Employee emp = new Employee();
            emp.Address = AddressEntry.Text;   
            App.Database.SaveItem(emp);
            this.Navigation.PushAsync(new EmployeeDetails());
  this.Navigation.PushModalAsync(new EmployeeDetails());
        }

เพื่อนำทางหนึ่งหน้าไปยังอีกหน้าหนึ่งด้วยเซลล์มุมมองด้านล่างรหัส Xamrian.forms

 private async void BtnEdit_Clicked1(object sender, EventArgs e)
        {
            App.Database.GetItem(empid);
            await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration(empid));
        }

ตัวอย่างเช่นด้านล่าง

public class OptionsViewCell : ViewCell
    {
        int empid;
        Button btnEdit;
        public OptionsViewCell()
        {
        }
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();

            if (this.BindingContext == null)
                return;

            dynamic obj = BindingContext;
            empid = Convert.ToInt32(obj.Eid);
            var lblname = new Label
            {
                BackgroundColor = Color.Lime,
                Text = obj.Ename,
            };

            var lblAddress = new Label
            {
                BackgroundColor = Color.Yellow,
                Text = obj.Address,
            };

            var lblphonenumber = new Label
            {
                BackgroundColor = Color.Pink,
                Text = obj.phonenumber,
            };

            var lblemail = new Label
            {
                BackgroundColor = Color.Purple,
                Text = obj.email,
            };

            var lbleid = new Label
            {
                BackgroundColor = Color.Silver,
                Text = (empid).ToString(),
            };

             //var lbleid = new Label
            //{
            //    BackgroundColor = Color.Silver,
            //    // HorizontalOptions = LayoutOptions.CenterAndExpand
            //};
            //lbleid.SetBinding(Label.TextProperty, "Eid");
            Button btnDelete = new Button
            {
                BackgroundColor = Color.Gray,

                Text = "Delete",
                //WidthRequest = 15,
                //HeightRequest = 20,
                TextColor = Color.Red,
                HorizontalOptions = LayoutOptions.EndAndExpand,
            };
            btnDelete.Clicked += BtnDelete_Clicked;
            //btnDelete.PropertyChanged += BtnDelete_PropertyChanged;  

            btnEdit = new Button
            {
                BackgroundColor = Color.Gray,
                Text = "Edit",
                TextColor = Color.Green,
            };
            // lbleid.SetBinding(Label.TextProperty, "Eid");
            btnEdit.Clicked += BtnEdit_Clicked1; ;
            //btnEdit.Clicked += async (s, e) =>{
            //    await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration());
            //};

            View = new StackLayout()
            {
                Orientation = StackOrientation.Horizontal,
                BackgroundColor = Color.White,
                Children = { lbleid, lblname, lblAddress, lblemail, lblphonenumber, btnDelete, btnEdit },
            };

        }

        private async void BtnEdit_Clicked1(object sender, EventArgs e)
        {
            App.Database.GetItem(empid);
            await App.Current.MainPage.Navigation.PushModalAsync(new EmployeeRegistration(empid));
        }



        private void BtnDelete_Clicked(object sender, EventArgs e)
        {
            // var eid = Convert.ToInt32(empid);
            // var item = (Xamarin.Forms.Button)sender;
            int eid = empid;
            App.Database.DeleteItem(empid);
        }

    }


2
In App.Xaml.Cs:

MainPage = new NavigationPage( new YourPage());

เมื่อคุณต้องการนำทางจาก YourPage ไปยังหน้าถัดไปให้ทำ:

await Navigation.PushAsync(new YourSecondPage());

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการนำทาง Xamarin Forms ได้ที่นี่: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/navigation/hierarchical

Microsoft มีเอกสารที่ค่อนข้างดีในเรื่องนี้

นอกจากนี้ยังมีแนวคิดใหม่ของไฟล์Shell. ช่วยให้มีวิธีใหม่ในการจัดโครงสร้างแอปพลิเคชันของคุณและทำให้การนำทางง่ายขึ้นในบางกรณี

Intro: https://devblogs.microsoft.com/xamarin/shell-xamarin-forms-4-0-getting-started/

วิดีโอเกี่ยวกับพื้นฐานของ Shell: https://www.youtube.com/watch?v=0y1bUAcOjZY&t=3112s

เอกสาร: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/


0

หน้า XAML เพิ่มสิ่งนี้

<ContentPage.ToolbarItems>
            <ToolbarItem Text="Next" Order="Primary"
            Activated="Handle_Activated"/>

</ContentPage.ToolbarItems>   

ในหน้า CS

 async void Handle_Activated(object sender, System.EventArgs e)
        {
            await App.Navigator.PushAsync(new PAGE());
        }

0

หลังจากPushAsyncใช้งานPopAsync(ด้วยthis) เพื่อลบหน้าปัจจุบัน

await Navigation.PushAsync(new YourSecondPage());
this.Navigation.PopAsync(this);

0

ใน Xamarin เรามีเพจชื่อว่า NavigationPage มันมีสแต็กของ ContentPages NavigationPage มีวิธีการเช่น PushAsync () และ PopAsync () PushAsync เพิ่มเพจที่ด้านบนสุดของสแต็กในขณะนั้นเพจเพจนั้นจะกลายเป็นเพจที่ใช้งานอยู่ในปัจจุบัน PopAsync () วิธีการลบหน้าออกจากด้านบนของสแต็ก

ใน App.Xaml.Cs เราสามารถตั้งค่าเช่น.

MainPage = NavigationPage ใหม่ (YourPage ใหม่ ());

รอการนำทาง PushAsync (newPage ใหม่ ()); วิธีนี้จะเพิ่มnewPageที่ด้านบนสุดของสแต็ก ในขณะนี้ nePage จะเป็นหน้าที่ใช้งานอยู่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.