Xamarin中其他类的访问方法

时间:2018-10-12 20:14:41

标签: c# xamarin xamarin.forms

我遇到了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>

两个虚拟机:为标签和按钮提供两个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的而不是真正的对象实例引用了RegX。但是如何找到编译器为实例创建的名称?

2 个答案:

答案 0 :(得分:0)

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应用程序的推荐结构。

答案 1 :(得分:0)

在您的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!
    }