【问题标题】:Access Method from other Class in XamarinXamarin 中其他类的访问方法
【发布时间】:2019-03-18 02:14:22
【问题描述】:

我遇到了 Xamarin 问题。我有一个 XAML ContentPage 文件,它由 StackLayout 中的两个 ContentView (vm:) 组成:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:Proj1"
            xmlns:vm="clr-namespace:Proj1.ViewModels"
            x:Class="Proj1.MyMain">

    <StackLayout BackgroundColor="{StaticResource MainBG}" Spacing="1">
        <vm:DisplayArea />
        <vm:ButtonArea />
    </StackLayout> 
</ContentPage>

两个 vm:为标签和按钮呈现两个 ContentView 区域。为了简单起见,我将它们分开并保持 XAML 文件更小。

所以,一般的,合并 XAML 结构如下所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:local="clr-namespace:Proj1"
            xmlns:vm="clr-namespace:Proj1.ViewModels"
            x:Class="Proj1.MyMain">

    <StackLayout BackgroundColor="{StaticResource MainBG}" Spacing="1">
        <ContentView>
            ...
            <Label Grid.Row="0" Grid.Column="1" x:Name="InpRegX" />
            ...
        </ContentView>

        <ContentView>
            ...
            <Button ... Clicked="BtnClicked" />
            ...
        </ContentView>
    </StackLayout> 
</ContentPage>

但我想将两个 ContentView 放在单独的文件中。

DisplayArea 包括一个标签 RegX:

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            x:Class="Proj1.ViewModels.DisplayArea">
    ...
    <Label Grid.Row="0" Grid.Column="1" x:Name="InpRegX" />
    ...
</ContentView>


namespace Proj1.ViewModels
{
    public partial class DisplayArea : ContentView
    {
        public readonly MyClass RegX;  // made public for simplicity

        public DisplayArea ()
        {
            InitializeComponent ();

            RegX = new MyClass(InpRegX);
        }
    }
}

现在我想从按钮时钟执行 DisplayArea.RegX 的 .AddChar() 方法。

namespace Proj1.ViewModels
{
    public partial class ButtonArea : ContentView
    {
        public ButtonArea ()
        {
            InitializeComponent ();
        }

        private void BtnClicked(object sender, EventArgs e)
        {
            var btn = (Button)sender;

            DisplayArea.RegX.AddChar(btn.Text);  // ERROR!
        }
    }
}

这会产生编译器错误:

非静态字段、方法或属性“DisplayArea.RegX”需要对象引用

这是因为我通过它的引用RegX,而不是真正的对象实例。但是如何找到编译器为实例创建的名称?

【问题讨论】:

标签: c# xamarin xamarin.forms


【解决方案1】:

OOP 中的标准是为实用程序创建一个静态类,该类具有全局且可访问的静态方法,就像您在每次想要访问变量或方法时都无需创建该类的实例一样。

例子:

public static class Util
{
    public static string GlobalString = "Hello World";

    public static string GetCurrentLanguage()
    {
        string SelectedLangProp;

        if (Application.Current.Properties.ContainsKey("SelectedLangProp"))
        {
            SelectedLangProp = Application.Current.Properties["SelectedLangProp"] as string;
        }
        else
        {
            SelectedLangProp = "AR";//default language
        }

        return SelectedLangProp;
    }
}

您可以使用以下方式从任何地方访问静态变量:

String TestGlobal = Util.GlobalString; //"Hello World"

方法调用也是如此:

String MethodResult = Util.GetCurrentLanguage();

还有一种更接近您所要求的替代方法:

DisplayArea display = new DisplayArea();
String Result = display.RegX.AddChar(btn.Text);

这会起作用,但它会创建一个新的类实例,特别是因为您使用的是 contentview 类并且在代码中执行逻辑而不是使用 MVVM 是构建 Xamarin 应用程序的推荐结构,所以不建议这样做。

【讨论】:

  • 我知道静态变量的概念。但我认为这在这里行不通。 Visual Studio 自动将 DisplayArea 创建为“公共 partial 类”。我无法将其更改为静态,因为这会产生很多其他错误。 (我用一些额外的信息增强了我最初的问题)
【解决方案2】:

在您的 XAML 中,分配一个名称

<vm:DisplayArea x:Name="MyDisplayArea />

然后在您的 xaml.cs 中

private void BtnClicked(object sender, EventArgs e)
    {
        var btn = (Button)sender;

        MyDisplayArea.RegX.AddChar(btn.Text);  // ERROR!
    }

【讨论】:

  • 嗨,Jason,这将是一个很酷的解决方案,但似乎不起作用,因为 vm:DisplayArea 在其他地方并不为人所知。我尝试使用 'x:Name="MyDisplayArea"' 来命名该 ContentArea,但随后错误消息指出 当前上下文中不存在名称 'MyDisplayArea'。
  • 再次查看您的代码,您似乎正在尝试将父 ContentPage 修改为 ContentArea 的代码隐藏。这行不通。您要么需要在 ContentArea 中公开页面可以响应的事件处理程序,要么使用 MessagingCenter
猜你喜欢
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多