根据单击的按钮将数字键盘的文本绑定到数量或单价

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

我有一个视图模型:

public partial class ItemViewModel : ObservableObject
{
    [ObservableProperty]
    double _quantity;

    [ObservableProperty]
    double _price;

    [ObservableProperty]
    string _selectedProperty;

    [RelayCommand]
    void SetSelectedProperty(string selectedProperty)
                 => SelectedProperty = selectedProperty;
}

自定义控件

Numpad
:

public partial class Numpad : ContentView
{
    double? _value;

    public static readonly BindableProperty TextProperty =
           BindableProperty.Create(
               propertyName: nameof(Text),
               returnType: typeof(string),
               defaultValue: "0",
               defaultBindingMode: BindingMode.TwoWay,
               declaringType: typeof(Numpad),
               propertyChanged: (bindable, oldValue, newValue) =>
               {
                   var @this = (Numpad)bindable;
                   ((Command)@this.UpCommand).ChangeCanExecute();
                   ((Command)@this.DownCommand).ChangeCanExecute();
               });

    public string Text
    {
        get => (string)GetValue(TextProperty);
        set => SetValue(TextProperty, value);
    }

    public ICommand UpCommand { get; }
    public ICommand DownCommand { get; }

    public Numpad()
    {
        UpCommand = new Command(
            execute: () =>
            {
                Text = $"{_value + 1}";
            },
            canExecute: () =>
            {
                if (double.TryParse(Text, out double x))
                {
                    _value = x;
                    return true;
                }

                _value = null;
                return false;
            }
        );

        DownCommand = new Command(
            execute: () =>
            {
                Text = $"{_value - 1}";
            },
            canExecute: () =>
            {
                if (double.TryParse(Text, out double x))
                {
                    _value = x;
                    return _value > 0;
                }

                _value = null;
                return false;
            }
        );
        InitializeComponent();
    }
}

及其 XAML:

<ContentView
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:loc="clr-namespace:MyProject.Views"
    x:Class="MyProject.Views.Numpad"
    x:Name="This">
    <VerticalStackLayout BindingContext="{Reference This}">
        <Button
            Text="Up"
            Command="{Binding UpCommand}" />
        <Button
            Text="Down"
            Command="{Binding DownCommand}" />
    </VerticalStackLayout>
</ContentView>

两者都在

MainPage
中使用,如下所示:

public MainPage()
{
    InitializeComponent();
    BindingContext = new ItemViewModel { Quantity = 3, Price = 5 };
}
<ContentPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:loc="clr-namespace:MyProject.Views"
    xmlns:vm="clr-namespace:MyProject.ViewModels"
    x:Class="MyProject.MainPage"
    x:DataType="vm:ItemViewModel"
    Title="Main Page">
    <VerticalStackLayout>
        <Button
            Text="{Binding Quantity}"
            Command="{Binding SetSelectedPropertyCommand}"
            CommandParameter="Quantity" />  
        <Button
            Text="{Binding Price}"
            Command="{Binding SetSelectedPropertyCommand}"
            CommandParameter="Price" />
        <loc:Numpad>
            <loc:Numpad.Triggers>
                <DataTrigger
                    TargetType="loc:Numpad"
                    Binding="{Binding SelectedProperty}"
                    Value="Quantity">
                    <Setter
                        Property="Text"
                        Value="{Binding Quantity,Mode=TwoWay}" />
                </DataTrigger>
                <DataTrigger
                    TargetType="loc:Numpad"
                    Binding="{Binding SelectedProperty}"
                    Value="Price">
                    <Setter
                        Property="Text"
                        Value="{Binding Price,Mode=TwoWay}" />
                </DataTrigger>
            </loc:Numpad.Triggers>
        </loc:Numpad>
    </VerticalStackLayout>
</ContentPage>

预期行为

  • 单击前 2 个按钮之一,应将
    Text
    Numpad
    绑定到
    Quantity
    UnitPrice
  • 单击
    Numpad
    中的任何按钮都会更改前 2 个按钮中所选按钮的
    Text
    属性。

不幸的是它不起作用,

Text
不会改变。

罪魁祸首是什么?

c# maui
1个回答
0
投票

您可以将

UpCommand
DownCommand
放入
ItemViewModel
中,这样您就可以直接操作数量价格,而无需使用触发器。

您不需要设置Reference扩展来设置

BindingContext
(或者甚至不需要
TextProperty
来设置Numpad)。
<loc:Numpad>
将从其父级/MainPage继承BindingContext,也就是说小键盘的BindingContext默认为ItemViewModel

//no need to set the BindingContext
<VerticalStackLayout>
    <Button
        Text="Up"
        Command="{Binding UpCommand}" />
    <Button
        Text="Down"
        Command="{Binding DownCommand}" />
</VerticalStackLayout>

并在ItemViewModel中,定义向上按钮向下按钮的命令。

    [RelayCommand]
    void Up(string selectedProperty)
    {
        if (SelectedProperty == "Quantity")
            Quantity += 1;
        else
            Price += 1;

    }


    [RelayCommand]
    void Down(string selectedProperty)
    {
        if (SelectedProperty == "Quantity")
            Quantity -= 1;
        else
            Price -= 1;
    }

希望有帮助!

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