简体   繁体   English

在Xamarin.Forms中,如果无法从XAML实例化BindingContext,如何在XAML代码中允许自动完成绑定?

[英]In Xamarin.Forms, how to allow for autocompletion for bindings in XAML code in the case you can't instantiate the BindingContext from XAML?

Given the following project: 鉴于以下项目:

MainPage.xaml MainPage.xaml中

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="A.MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:A">
    <ContentPage.Content>
        <StackLayout>
            <StackLayout>
                <Button Clicked="Greet" Text="Greet" />
            </StackLayout>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

MainPage.xaml.cs MainPage.xaml.cs中

using System;
using Xamarin.Forms;

namespace A
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void Greet(object sender, EventArgs e)
        {
            Navigation.PushModalAsync(new SubPage
            {
                BindingContext = new SubPageViewModel("World")
            });
        }
    }
}

SubPage.xaml SubPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="A.SubPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <ContentPage.Content>
        <StackLayout>
            <Label
                HorizontalOptions="CenterAndExpand"
                Text="{Binding Greeting}"
                VerticalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SubPage.xaml.cs SubPage.xaml.cs

using Xamarin.Forms;

namespace A
{
    public partial class SubPage : ContentPage
    {
        public SubPage ()
        {
            InitializeComponent ();
        }
    }
}

SubPageViewModel.cs SubPageViewModel.cs

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace A
{
    public class SubPageViewModel : INotifyPropertyChanged
    {
        private string place;

        public string Place
        {
            get => place;
            set
            {
                if(place != value)
                    return;
                place = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(Greeting));
            }
        }

        public SubPageViewModel(string place)
        {
            this.place = place;
        }

        public string Greeting => $"Hello, {place}";

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Visual Studio won't autocomplete bindings in SubPage.xaml and will be complaining that it "Cannot resolve symbol 'Greeting' due to unknown DataContext", because the syntax highlighter doesn't know the type at the compile time. Visual Studio不会在SubPage.xaml中自动完成绑定,并且会抱怨它“由于未知的DataContext而无法解析符号'问候',因为语法高亮显示器在编译时不知道类型。 Typically, I'd use the following syntax: 通常,我使用以下语法:

<ContentPage.BindingContext>
    <a:SubPageViewModel />
</ContentPage.BindingContext>

however, this isn't applicable here, since the ViewModel is not default constructible. 但是,这不适用于此,因为ViewModel不是默认可构造的。

If this was WPF, I'd be using mc:Ignorable="d" together with d:DesignInstance , however, DesignInstance doesn't seem to be implemented in XF. 如果这是WPF,我将使用mc:Ignorable="d"d:DesignInstance ,但是, DesignInstance似乎没有在XF中实现。

How do I make autocompletion work? 如何使自动完成工作?

You can declare a dummy static property which will be used in a binding. 您可以声明将在绑定中使用的虚拟静态属性。

SubPage.xaml SubPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="A.SubPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:a="clr-namespace:A;assembly=A.Android"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    BindingContext="{x:Static a:SubPage.BindingContextDummyInstance}"> <!-- <------ added -->
    <ContentPage.Content>
        <StackLayout>
            <Label
                HorizontalOptions="CenterAndExpand"
                Text="{Binding Greeting}"
                VerticalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SubPage.xaml.cs SubPage.xaml.cs

using Xamarin.Forms;

namespace A
{
    public partial class SubPage : ContentPage
    {
        public static SubPageViewModel BindingContextDummyInstance => null; // <------ added

        public SubPage ()
        {
            InitializeComponent ();
        }
    }
}

This changes nothing with regards to code semantics since the default BindingContext is still null , but now autocompletion is working, because the BindingContext is known at compile time. 这对代码语义没有任何改变,因为默认的BindingContext仍为null ,但现在自动完成正在工作,因为BindingContext在编译时是已知的。

You can try: 你可以试试:

<ContentPage.BindingContext>
    <x:Type Type="a:SubPageViewModel " />
</ContentPage.BindingContext>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM