如何从平板电脑/手机模板访问背后的代码?

时间:2019-05-15 23:01:52

标签: xaml xamarin xamarin.forms

我正在接管一个项目,该项目具有通过DI的ViewModelLocator链接的DashboardPage和DashboardPageViewModel。 “仪表板”页面包含以下代码,可将Xaml /代码幕后分为两个单独的模板。

   private void SetContent()
        {
            Debug.WriteLine("Dashboardpage setContent");

            switch(Device.Idiom)
            {
                case TargetIdiom.Phone:
                    Content = new PrimaryPhoneLayout
                    {
                        RegionContent = RegionContent
                    };
                    break;
                case TargetIdiom.Tablet:
                    Content = new PrimaryTabletLayout(deviceDisplay)
                    {
                        RegionContent = RegionContent
                    };
                    break;
                default:
                    throw new NotSupportedException($"{Device.Idiom} is not a supported idom");
            }
        }

我想在Phone / Tablet xaml中都添加一个按钮,并处理DashboardPage中的逻辑。这些XAML文件链接到其背后的单独代码而不是Dashboard页面时,如何引用Dashboard页面?

为进一步详细说明,DashboardPage从MenuContainerPage派生而来,它使我可以滑入/滑出幻灯片菜单。我想通过在平板电脑/手机布局中都实现的按钮来处理这种逻辑。

2 个答案:

答案 0 :(得分:3)

这就是我要做的。

我首先创建一个interface,其中包含我想从我的ContentView公开的事件

对于示例,我将此接口称为IMenuOptionHandler,看起来像这样

public interface IMenuOptionHandler
{
    event EventHandler OnSlideIn;

    event EventHandler OnSlideOut;
}

在这里,我们有两个事件将从ContentViews中调用。您可以根据需要添加任意数量。

然后,我们需要制作ContentViews来实现此接口:

public partial class PrimaryPhoneLayouts : ContentView, IMenuOptionHandler
{
    //...

    #region "IMenuOptionHandler implementation"
    public event EventHandler OnSlideIn;

    public event EventHandler OnSlideOut;
    #endregion

    void OnSlideInButtonClicked(object sender, EventArgs e)
    {
        OnSlideIn?.Invoke(this, EventArgs.Empty);
    }

    void OnSlideOutButtonClicked(object sender, EventArgs e)
    {
        OnSlideOut?.Invoke(this, EventArgs.Empty);
    }
}

public partial class PrimaryTabletLayout : ContentView, IMenuOptionHandler
{
    // ...

    #region "IMenuOptionHandler implementation"
    public event EventHandler OnSlideIn;

    public event EventHandler OnSlideOut;
    #endregion

    void OnSlideInButtonClicked(object sender, EventArgs e)
    {
        OnSlideIn?.Invoke(this, EventArgs.Empty);
    }

    void OnSlideOutButtonClicked(object sender, EventArgs e)
    {
        OnSlideOut?.Invoke(this, EventArgs.Empty);
    }

您可以看到两个类都在实现我们的接口。

此外,我添加了两组方法,它们是您将挂钩到XAML上的按钮的方法。

假设您的XAML如下所示:

<ContentView.Content>
    <StackLayout Orientation="Vertical" 
                 HorizontalOptions="FillAndExpand">
        <Button Text="SlideIn" 
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="FillAndExpand" 
                Clicked="OnSlideInButtonClicked" />
        <Button Text="SlideOut" 
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="FillAndExpand" 
                Clicked="OnSlideOutButtonClicked" />           
    </StackLayout>
</ContentView.Content>

两个XAML都应在类后面的代码中将按钮和Clicked事件连接到我们的方法。

这两种方法(到目前为止)的唯一目的是调用事件并通知任何已订阅事件的人。

现在进入您的DashboardPage

为简单起见,您将添加此全局属性

IMenuOptionHandler MenuOptionHandler => Content as IMenuOptionHandler;

这会将页面内容转换为IMenuOptionHandler。任何实现此接口的类都将允许这种强制转换。

要添加到同一DashboardPage上的最后一部分是事件的订阅。这些将以OnAppearing方法发生,我们将取消订阅OnDisappearing

protected override void OnAppearing()
{
    base.OnAppearing();

    if (MenuOptionHandler != null)
    {
        MenuOptionHandler.OnSlideIn += MenuOptionHandler_OnSlideIn;
        MenuOptionHandler.OnSlideOut += MenuOptionHandler_OnSlideOut;
    }
}

protected override void OnDisappearing()
{
    base.OnDisappearing();

    if (MenuOptionHandler != null)
    {
        MenuOptionHandler.OnSlideIn -= MenuOptionHandler_OnSlideIn;
        MenuOptionHandler.OnSlideOut -= MenuOptionHandler_OnSlideOut;
    }
}

void MenuOptionHandler_OnSlideIn(object sender, EventArgs e)
{
    //Logic to handle the SlideIn
    Debug.WriteLine("MenuOptionHandler_OnSlideIn");
}

void MenuOptionHandler_OnSlideOut(object sender, EventArgs e)
{
    //Logic to handle the SlideOut
    Debug.WriteLine("MenuOptionHandler_OnSlideOut");
}

现在,只要单击ContentView(iPhone或平板电脑)上的按钮之一,仪表板ContentPage就会收到有关此通知,您将可以执行任何任务希望。

希望这会有所帮助。-

答案 1 :(得分:0)

假设您在Page1中有一个按钮,请首先为Xaml中的按钮命名:

<Button x:Name="btnInPage1" Text="Welcome to Xamarin.Forms!" />

在Page1后面的代码中,创建button的public static属性,并设置btnPageOne = btnInPage1

public partial class Page1 : ContentPage
{

    public static Button btnPageOne;
    public Page1 ()
    {
        InitializeComponent ();

        btnPageOne = btnInPage1;

    }
}

然后在DashboardPage中,您可以使用Page1.btnPageOne访问按钮,并使用以下命令处理逻辑:

Page1.btnPageOne.Clicked += delegate {

    Console.WriteLine("Page1 btn clicked");

};

如果您拥有Page2,Page3 ...