XAML .net Maui绑定值多个级别深

ikfrs5lh  于 2022-12-07  发布在  .NET
关注(0)|答案(2)|浏览(180)

如何将绑定从Page传递到View
我有这个页面(Xaml)

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:DataBindingTests.Views"
             xmlns:model="clr-namespace:DataBindingTests.ViewModels"
             x:Class="DataBindingTests.Pages.CoolePage"
             Title="CoolePage"
             x:DataType="model:CoolesModel">
    <VerticalStackLayout>
        <Label Text="{Binding YourName}"></Label>
        <views:MainView YourName="{Binding YourName}"></views:MainView>
        <Button Command="{Binding ChangeNameCommand}"></Button>
    </VerticalStackLayout>
</ContentPage>

及其CodeBehind:

using DataBindingTests.ViewModels;

namespace DataBindingTests.Pages;

public partial class CoolePage : ContentPage
{
    public CoolePage()
    {
        this.BindingContext = new CoolesModel();
        InitializeComponent();
    }
}

如果我将一个String传递给我的MainView,它就会工作,并且会触发所有事件。当我使用绑定时,它不会。在这个简单的测试中,应用程序应该会显示两次相同的名称,但只有ContentPage的Label会打印YourName属性
<views:MainView YourName="Lars"></views:MainView>〈--工程
<views:MainView YourName="{Binding YourName}"></views:MainView>〈--不起作用

这是主视图的XAML

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:views="clr-namespace:DataBindingTests.Views"
             x:Class="DataBindingTests.Views.MainView">
    <VerticalStackLayout>
        <Label Text="{Binding YourName}"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentView>

这是主视图的代码隐藏

namespace DataBindingTests.Views;

public partial class MainView : ContentView
{
    public String YourName
    {
        get
        {
            String value = (String)GetValue(MainView.YourNameProperty);
            return value;
        }
        set
        {
            SetValue(MainView.YourNameProperty, value);
        }
    }

    public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
    , typeof(String)
    , typeof(MainView), defaultBindingMode:BindingMode.TwoWay, propertyChanged: OnYourNameChanged);

    static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
    {
        Console.WriteLine(newValue);
    }

    public MainView()
    {
        this.BindingContext = this; // Ignore ParentContext
        InitializeComponent();
    }
}
mbskvtky

mbskvtky1#

您只需从MainView.xaml.cs的构造函数中删除代码this.BindingContext = this;即可:

public MainView()
    {
        //this.BindingContext = this;
        InitializeComponent();
    }

更新日期:

上面的代码之所以有效是因为视图和页面中的属性具有相同的名称。
在这种情况下,您可以修改MainView.xaml的代码,如下所示:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp929.MainView"
             x:Name="TestControlView"
             >
    <VerticalStackLayout>
        <Label   Text="{Binding Source={x:Reference TestControlView}, Path=YourName}"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentView>

MainView.xaml.cs

public partial class MainView : ContentView 
{

    public String YourName
    {
        get
        {
            String value = (String)GetValue(YourNameProperty);
            return value;
        }
        set
        {
            SetValue(YourNameProperty, value);
        }
    }

    public static readonly BindableProperty YourNameProperty = BindableProperty.Create(nameof(YourName)
    , typeof(String)
    , typeof(MainView), defaultBindingMode: BindingMode.TwoWay, propertyChanged: OnYourNameChanged);

    static void OnYourNameChanged(BindableObject bindable, object oldValue, object newValue)
    {
        Console.WriteLine("-----------------> "+newValue);
    }
    public MainView()
      {
            InitializeComponent();

       // this.BindingContext = this;
    }
}

CoolesModel.cs

public class CoolesModel 
{
    //  public string YourName { get; set; }
    public string Name { get; set; }

    public string TestName { get; set; }

    public ICommand ChangeNameCommand => new Command(changeMethod);

    private void changeMethod()
    {

    }

    public CoolesModel() {
        //YourName = "abc";
        Name = "abc";

        TestName = "test123...";
    }
}

MainPage.xaml.cs

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:mauiapp929="clr-namespace:MauiApp929"
             x:Class="MauiApp929.MainPage">
  
    <ScrollView>
        <VerticalStackLayout>
            <Label Text="{Binding Name}"></Label>
            <mauiapp929:MainView YourName="{Binding TestName}"></mauiapp929:MainView>
            <Button Command="{Binding ChangeNameCommand}"></Button>
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>
zzlelutf

zzlelutf2#

在这个简单的测试中,应用程序应该显示两次相同的名称,但只有ContentPage的Label打印了YourName属性
由于某种原因,您在中途覆盖了绑定上下文,并且页面绑定解析的上下文(通常使用它的方式,父上下文)与您在屏幕上实际看到的内容(即this.BindingContext = this)不同,而且您从未设置第二个上下文的属性。

相关问题