如何在WPF中将十进制值作为CommandParameter传递给命令?

3

我有一个使用C#和WPF编写的应用程序,它是在Prism 6框架之上构建的。

我正在尝试使用XAML创建一个按钮,当点击时,我想要将一个固定的小数值传递给我的视图模型。

<Button Content="5"
        VerticalAlignment="Center"
        HorizontalAlignment="Center"
        Command="{Binding ProcessAmount}"
        CommandParameter="5.00000"
        FontSize="24"
        Height="75"
        Width="85" />

在我的视图模型中,我有以下内容:
public class ViewModel : BindableBase
{
    public DelegateCommand<decimal?> ProcessAmount { get; set; }

    public ViewModel()
    {
        ProcessAmount = new DelegateCommand<decimal?>(HandleProcessAmount, CanProcessAmount);
    }

    private bool CanProcessAmount(decimal? amount)
    {
        return amount.HasValue && amount.Value != 0;
    }

    private void HandleProcessAmount(decimal? amount)
    {
        // do something with the amount
    }
}

但是当我编译应用程序时,在XAML视图中出现错误指定的转换无效。

我该如何从视图中发送一个固定的十进制值?

3个回答

5
在XAML世界中,每个数字都被视为Double类型。否则可能会发生意外情况,您需要手动进行类型转换/转换。这意味着,在您的视图模型中,应将数字作为double?而不是decimal?检索,然后根据需要将其强制转换/转换为十进制数。例如:
public class ViewModel : BindableBase
{
    public DelegateCommand<double?> ProcessAmount { get; set; }

    public ViewModel()
    {
        ProcessAmount = new DelegateCommand<double?>(HandleProcessAmount, CanProcessAmount);
    }

    private bool CanProcessAmount(double? amount)
    {
        return amount.HasValue && amount.Value != 0;
    }

    private void HandleProcessAmount(double? amount)
    {
        decimal amountInDecimal = Convert.ToDecimal(amount.Value); // convert it to decimal

        // do something with the amount
    }
}

好处在于对于double类型的数字进行计算比decimal类型更容易。但是,我想这不是你想要的。

解决你问题的方法是在xaml中明确指定类型为Decimal。你需要导入System mscorlib,然后将该SystemDecimal赋值给CommandParameter

xmlns:s="clr-namespace:System;assembly=mscorlib"

<Button Content="5"
        VerticalAlignment="Center"
        HorizontalAlignment="Center"
        Command="{Binding ProcessAmount}"
        FontSize="24"
        Height="75"
        Width="85">
    <Button.CommandParameter>
        <s:Decimal>5.00000</s:Decimal>
    </Button.CommandParameter>
</Button>

这样可以避免在虚拟机端进行数字类型转换的必要性。

由于某些有趣的原因,这在UWP中无法正常工作。 - Shimmy Weitzhandler
明白了,根据这里的说明,应该是 x:Int32 - Shimmy Weitzhandler

2

不要直接将5.00000赋值给CommandParameter,尝试在XAML中定义该值作为资源(参考此主题)。您的XAML代码可能如下所示:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:system="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow"
        Height="450"
        Width="800">

    <Window.Resources>
        <system:Double x:Key="MyDouble">5.0000</system:Double>
    </Window.Resources>

    <Grid>
        <Button Content="5"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Command="{Binding ProcessAmount}"
                CommandParameter="{StaticResource MyDouble}"
                FontSize="24"
                Height="75"
                Width="85" />
    </Grid>
</Window>

0
你遇到的问题是,你将字符串“5”分配给了 CommandParameter。有几种解决方案。其中之一是在 XAML 中设置 Decimal:
<Window x:Class="....." 
xmlns:sys="clr-namespace:System;assembly=mscorlib"  
/>
<Button Content="5"
    VerticalAlignment="Center"
    HorizontalAlignment="Center"
    Command="{Binding ProcessAmount}"
    FontSize="24"
    Height="75"
    Width="85">
    <Button.CommandParameter><sys:Decimal>5.00000</sys:Decimal></Button.CommandParameter>
    <!-- <Button.CommandParameter><x:Null/></Button.CommandParameter> If you want to set value to null-->
</Button>


或者将ComandParameter作为字符串处理:

public class ViewModel : BindableBase
{
    public DelegateCommand<string> ProcessAmount { get; set; }

    public ViewModel()
    {
        ProcessAmount = new DelegateCommand<string>(HandleProcessAmount, CanProcessAmount);
    }

    private bool CanProcessAmount(string amountStr)
    {
        try
        {
            return Convert.ToDecimal(amountStr) != 0;
        }
        catch (Exception)
        {
            return false;
        }
    }

    private void HandleProcessAmount(string amount)
    {
        // do something with the amount
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接