【问题标题】:Add multiple bindingcontexts to xaml file将多个绑定上下文添加到 xaml 文件
【发布时间】:2019-06-02 13:18:31
【问题描述】:

我尝试实现我的第一个 MVVM 项目。 首先,我创建了名为“person.cs”的模型。 然后我创建了一个模型视图“AddPerson.cs”,它应该动态创建存储在 person.cs 中的数据。 在我看来(完全用 xaml 创建)我有一个按钮,它应该从我的“AddPerson.cs”调用方法“CreatePerson()”。我喜欢绑定方法。

此外,我创建了一个标签,它应该绑定到类“person.cs”,例如绑定到公共字符串“Name”。

如何将 Button 的 BindingContext 设置为“AddPerson.cs”-class,将 Label 的 BindingContext 设置为“person.cs”-class?

【问题讨论】:

  • 不可能你想做的事,但你为什么不创建一个 PersonViewModel 并将其用作你的 BindingContext ?在这里,您可以拥有AddPerson 方法和带有Person 的属性。 ViewModel 非常适合这种情况。

标签: xaml xamarin binding-context


【解决方案1】:

是的,这是可能的。 大多数元素继承BindablObject。每个BindableObjaect 都有一个BindingContext 属性。 见:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-binding-basics

MainViewModel

整个页面的视图模型,包含每个子视图模型。

public class MainViewModel
{
    public AddPersonViewModel AddPersonViewModel { get; }
    public PersonViewModel PersonViewModel { get; }

    public MainViewModel()
    {
        // the passed action is just a fake action to simulate adding a person
        AddPersonViewModel = new AddPersonViewModel(value => PersonViewModel.Name = value);
        PersonViewModel = new PersonViewModel();
    }
}

AddPersonViewModel

包含您的添加逻辑。

public class AddPersonViewModel : INotifyPropertyChanged
{ 
    public AddPersonViewModel(Action<string> onAction)
    {
        AddPerson = new Command(() => 
        {
            onAction(NewName); // call your update logic
            NewName = ""; // reset name
        });
    }

    public Command AddPerson { get; }
    private string _name;

    public string NewName
    {
        get => _name;
        set
        {
            _name = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NewName)));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

PersonViewModel

包含您的“新”人物。

public class PersonViewModel : INotifyPropertyChanged
{
    private string _name;

    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

主页

创建并设置您的 MainViewModel。

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        BindingContext = new MainViewModel();
    }
}

MainPage.xaml

在这里,我们将EntryButtonBindingContext 绑定到ContentPage's BindingContextAddPersonViewModel 属性,即MainViewModel。然后我们将LabelTextButtonCommand绑定到本地BindingContextNewNameAddPerson属性,即AddPersonViewModel

Label 也一样。

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

    <StackLayout>
        <Entry BindingContext="{Binding AddPersonViewModel}" Text="{Binding NewName}" 
           HorizontalOptions="FillAndExpand" />
        <Button BindingContext="{Binding AddPersonViewModel}" Text="Click me!" Command="{Binding AddPerson}" 
           HorizontalOptions="Center" />
        <Label Text="Added Person:" FontAttributes="Bold" 
           HorizontalOptions="Center"/>
        <Label BindingContext="{Binding PersonViewModel}" Text="{Binding Name}" 
           HorizontalOptions="Center"/>
    </StackLayout>

</ContentPage>

这个例子很老套,但我想你明白了。关键是已经提到的属性BindingContext

【讨论】:

  • 嗨,斯文-迈克尔!这正是我一直在寻找的地方。明天我会试试这个,但我认为你的详细答案是不言自明的。谢谢!古特之夜 ;-)
  • Ivan Ičin 的答案是更简单、更标准的方法。这里不需要多个视图模型。以上应该可行,但对我来说似乎不必要地复杂。
  • 是的,当然是,但我回答了您的问题“如何设置按钮的 BindingContext ....”。人们通常会简化他们的问题(好方法)。
【解决方案2】:

您缺少一些基本概念,导致您的请求很奇怪。

您不会将数据绑定到类定义,而是绑定到类的实例。由于一个 ViewModel 是一个类,它可能包含您数据绑定到的其他类的实例,除此之外的所有内容在 99% 的情况下都是错误的做法,而您的示例不是这 1% 的情况之一。

所以基本上你的 ViewModel 应该是这样的:

public class PersonViewModel
{
   public Person Person {get; set}
   public ICommand AddPersonCommand {get; set}
}

然后,您的 BindingContext 是 PersonViewModel 的一个实例,然后在 Label 上您将绑定到 Person,而在按钮上您将绑定到 AddPersonCommand。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-28
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多