C# 如何使用WPF将十进制值作为命令的CommandParameter传递?

C# 如何使用WPF将十进制值作为命令的CommandParameter传递?,c#,wpf,xaml,binding,prism,C#,Wpf,Xaml,Binding,Prism,我有一个在Prism 6框架上使用c#和WPF编写的应用程序 我正在尝试使用XAMl创建一个按钮,单击时,我希望向视图模型传递一个固定的十进制值 <Button Content="5" VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding ProcessAmount}" CommandParameter="5.00000"

我有一个在Prism 6框架上使用c#和WPF编写的应用程序

我正在尝试使用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
    }
}
public类ViewModel:BindableBase
{
公共DelegateCommand ProcessAmount{get;set;}
公共视图模型()
{
ProcessAmount=新的DelegateCommand(HandleProcessAmount、CanProcessAmount);
}
私人bool CanProcessAmount(十进制?金额)
{
返回amount.HasValue&&amount.Value!=0;
}
私有无效HandleProcessAmount(十进制?金额)
{
//用数量做点什么
}
}
但是当我编译应用程序时,我在XAML视图中得到一个错误
指定的强制转换无效。


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

请尝试将XAML中的值定义为资源,而不是将
5.00000
直接分配给
CommandParameter
。您的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>

5

在Xaml世界中,每个数字都被视为
Double
。您需要手动强制转换/转换,否则可能会发生意外情况。这意味着,在视图模型中,将数字检索为
double?
而不是
decimal?
,然后根据需要将其转换为
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
    }
}

这就消除了在VM端转换数字类型的必要性。

问题在于,您将
字符串
“5”分配给
命令参数。有几种解决方案。其中一个用于在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>
<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>
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
    }
}