如何在MVVM(.NET MAUI)中为自定义控件提供Command-Property

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

我正在尝试在 .NET MAUI 中构建自定义控件,该控件应为其父级提供 ICommand 的 BindableProperty。这是我试图实现的目标的基本示例。

主页视图 (MainPage.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:SampleApp.Views"
             x:Class="SampleApp.MainPage">

    <views:MyCustomControl DoSomething="{Binding DoSomethingCommand}"></views:MyCustomControl>
</ContentPage>

MainPage 视图类 (MainPage.xaml.cs)

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

MainPage 视图模型(MainPageViewModel.cs)

public class MainPageViewModel : ObservableObject
{
    public ICommand ProcessNewScoreCommand { get; }

    public MainPageViewModel()
    {
        ProcessNewScoreCommand = new Command(DoSomething);
    }

    private void DoSomething()
    {
        // Do something
    }
}

MyCustomControl 视图类 (MyCustomControl.xaml.cs)

public partial class MyCustomControl : ContentView
{
    public static readonly BindableProperty DoSomethingProperty =
        BindableProperty.Create(nameof(DoSomething), typeof(ICommand), typeof(MyCustomControl));

    public ICommand DoSomething
    {
        get => (ICommand)GetValue(DoSomethingProperty);
        set => SetValue(DoSomethingProperty, value);
    }

    public MyCustomControl()
    {
        InitializeComponent();
        BindingContext = new MyCustomControlViewModel(DoSomething);
    }
}

MyCustomControl 视图模型 (MyCustomControlViewModel.cs)

public class MyCustomControlViewModel : ObservableObject
{
    public ICommand DoSomething { get; }

    public MyCustomControlViewModel(ICommand doSomethingCommand)
    {
        DoSomething = doSomethingCommand;
    }

    private void PerformSomeLogic()
    {
        // Any calulations/logic
        // ...

        if (DoSomething.CanExecute(null))
        {
            // Execute command, so that parent component gets informed and can act.
            DoSomething.Execute(null);
        }
    }
}

调试时,类

DoSomething
的属性
MyCustomControl.xaml.cs
始终为空。而且,它的 setter 似乎在任何时候都不会被调用。我做错了什么?

c# .net mvvm maui
1个回答
7
投票

它不起作用的原因是您正在为自定义控件创建虚拟机,即视图,然后为其分配上下文,然后稍后在自定义控件中再次更改其 BindingContext,自定义控件不应该有自己的预定义绑定上下文。

解决此问题的步骤:

  • 删除您的

    MyCustomControlViewModel
    课程。

  • 现在您的 CustomControl.xaml.cs 将如下所示:

    public partial class MyCustomControl : ContentView
    {
    
       public static readonly BindableProperty DoSomethingProperty =
                    BindableProperty.Create(nameof(DoSomething), typeof(ICommand), typeof(MyCustomControl));
    
       public ICommand DoSomething
       {
          get => (ICommand)GetValue(DoSomethingProperty);
          set => SetValue(DoSomethingProperty, value);
       }
    
       public MyCustomControl()
       {
          InitializeComponent();
       }
    }
    
  • 现在你的View的VM应该是处理逻辑的VM,这样你就不会遇到多个令人困惑的BindingContext和编译器(通过在错误的位置搜索它):

    public class MainPageViewModel : ObservableObject
    {
        public ICommand DoSomething { get; }
    
        public MainPageViewModel()
        {
          DoSomething = new Command(DoSomething);
        }
    

祝你好运,如果您还有其他问题,请告诉我。

使用 XF 和 MAUI 的 MVVM 基本指南:https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvm

© www.soinside.com 2019 - 2024. All rights reserved.