.NET MAUI:想要将父对象传递给转换器和控件,但没有收到 OnPropertyChanged

问题描述 投票:0回答:1

我在 MAUI 中不断遇到这个问题,我怀疑这是由于对 MVVM 的一些基本误解造成的。

说我有:

public class Student : ObservableObject {
    [ObservableProperty] string _name;
    [ObservableProperty] double _GPA;
    [ObservableProperty] bool _isPassing;
}

我制作了一个自定义控件 (

StudentControl
) 来在应用程序中重复使用我的学生视图。我的直觉告诉我应该在
BindableProperty
类型的控件中创建一个
Student
。将学生绑定到控件,然后控件查找它需要显示的字段,并绑定到它们本身。我的想法是,
StudentControl
的工作是决定它想要显示有关学生的哪些内容。如果我想更改稍后显示的内容,或者添加/删除字段,我可以去那里执行此操作。

<controls:StudentControl Student={Binding SomeBindingToAStudentObject}>

然而,这似乎不是我在毛伊岛应该做的事情。当我将

Student
直接传递给控件时,绑定似乎会中断,因为更改的是属性,而不是
Student
对象本身。因此,尽管属性通知正确,但由于控件绑定到
Student
(而不是单个属性),因此即使属性更改,控件也不会更改。

我对转换器也有类似的问题,我想传递父 Student 对象,然后决定如何转换它,但同样,这会破坏绑定中的属性更改通知,因为它的链接是指向 Student,而不是更改的属性本身。

我知道我可以通过将字段单独传递到 MultiBinding 中的控件来解决此问题,但是如果我将来添加一个字段,我需要转到该控件的每次使用并向其添加该字段,而不是调整只是控制。

也许是一个重要的注意事项:我通常将 Student 对象放在 List 中,而不是直接引用,并通过 Bindabale 布局或集合视图等使用它们。

有什么建议可以改善这种情况吗?或者我是否坚持将各个属性传递给我的控件/转换器?

编辑:听起来我需要提供有关视图的更多背景信息。

这是一个非常复杂的问题,所以我试图稍微简化一下。

我有一个

ClassViewModel
支持
ClassView
,这是为了显示
ClassList : ObservableObject

ClassList
有一个

[ObservableProperty] BindingList<Student> _students;

所以在我的 ClassView 中,我有这样的东西:

            <StackLayout BindableLayout.ItemsSource="{Binding ClassList.Students}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate x:DataType="{x:Type models:Student}" >
                        <controls:StudentControl
                           Student="{Binding .}"/>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>

但是当

Student.Name
更改时控件不会更新。其他属性也一样。当我创建 3 个可绑定属性(每个字段一个)并将绑定作为
Student.Name
Student.GPA
等传递时,它就可以工作了。

          <!--This Works -->
          <StackLayout BindableLayout.ItemsSource="{Binding ClassList.Students}">
            <BindableLayout.ItemTemplate>
                <DataTemplate x:DataType="{x:Type models:Student}" >
                    <controls:StudentControl
                       Name="{Binding Student.Name}"
                       GPA="{Binding Student.GPA}"
                       IsPassing="{Binding Student.IsPassing}"/>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>

StudentControl
中,我有一个绑定到
Student.Name
的标签,并且我在 XAML 中将 BindingContext 设置为
This

标题中:

x:Name="This"

下:

<VerticalStackLayout BindingContext="{x:Reference This}"

请注意,如果我换出完全不同的学生,视图会发生变化,但编辑现有学生时不会发生变化。

.net xaml binding maui inotifypropertychanged
1个回答
0
投票

首先,集合不应该使用

[ObservableProperty]
属性,而应该使用
ObservableCollection
。集合的最佳实践不是更改集合,而是更改集合中的成员,因此,这就是为什么我们不会期望来自集合的 INotifyPropertyChanged 事件。

public ObservableCollection<Student> Students { get; } = new();

接下来,我希望如果你的控件需要更新Student,那么你所拥有的各种绑定需要更改为TwoWay,例如

<controls:StudentControl
    Name="{Binding Student.Name, Mode=TwoWay}"
    GPA="{Binding Student.GPA, Mode=TwoWay}"
    IsPassing="{Binding Student.IsPassing, Mode=TwoWay}"/>
© www.soinside.com 2019 - 2024. All rights reserved.