XAML 从未呼叫BindableProperty setter

omqzjyyz  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(98)

我在ListView的ItemTemplate中有一个绑定,

<ListView ItemsSource="{Binding Capsules}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <views:CapsuleWidgetView Model="{Binding}"/>
            </ViewCell>
        </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

在我的CapsuleWidgetView组件中,

public CapsuleWidgetViewModel ViewModel => (CapsuleWidgetViewModel)BindingContext;

public CapsuleModel Model
{
    get => (CapsuleModel)GetValue(ModelProperty);
    set => SetValue(ModelProperty, value);
}

public static readonly BindableProperty ModelProperty = BindableProperty.Create(
    nameof(Model),
    typeof(CapsuleModel),
    typeof(CapsuleWidgetView),
    propertyChanged: (bindable, value, newValue) =>
    {
        var view = (CapsuleWidgetView)bindable;
        var modelValue = (CapsuleModel)newValue;

        view.ViewModel.Capsule = modelValue;
    });

每当ListView的绑定集合发生更改时,这些项都会按预期重新生成。但是,每个Model始终为null,并且从未调用过属性setter。不是从ModelProperty propertyChanged调用的,也不是从我定义的setter方法调用的。我已经用调试器确认了这一点,并尝试进行日志记录。
我原本以为我的问题是来自binding being null,但事实似乎并非如此。我访问绑定对象的属性的另一个测试成功了。即使这样,源集合也永远不会有一个空对象添加到其中。

  • 但是 *,直接在Xaml中定义的CapsuleModel可以正常工作。
<views:CapsuleWidgetView>
    <views:CapsuleWidgetView.Model>
        <models:CapsuleModel Name="Hello?"/>
    </views:CapsuleWidgetView.Model>
</views:CapsuleWidgetView>

引用模型的属性并将它们绑定到类似Label.Text的东西是有效的,我确信问题源于我的BindableProperty和/或BindingContext

wztqucjr

wztqucjr1#

为什么<views:CapsuleWidgetView Model="{Binding}"/>没有绑定属性名称(如<views:CapsuleWidgetView Model="{Binding Model}"/>)?
在视图模型中:

[ObservableProperty]
private ObservableCollection<Capsule> Capsules;

而在模型中:

public class Capsule : ObservableObject
{
  private CapsuleModel model;
  public CapsuleModel Model
  {
   get => model;
   set => SetProperty(ref model, value);
  }
}
uujelgoq

uujelgoq2#

引用this answer
永远不要在ContentView中执行BindingContext = this;,因为它会从试图绑定到它的页面劫持上下文。
在我的例子中,BindingContext是在Xaml中设置的,它等效于BindingContext = this;

public CapsuleWidgetView()
{
    InitializeComponent();
        
    Content.BindingContext = new CapsuleWidgetViewModel();
}

请注意,它不能放在InitializeComponent之上,因为Content实际上还没有创建。

相关问题