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

时间:2018-05-09 01:11:28

标签: c# wpf xaml binding prism

我在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
    }
}

但是当我编译应用程序时,我在XAML视图中遇到错误Specified cast is not valid.

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

3 个答案:

答案 0 :(得分:2)

在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
    }
}

关于这一点的好处是,对double类型编号执行计算比decimal类型编号更容易。但是,我想这不是你想要的。

问题的解决方案是在xaml中明确指定类型Decimal。您需要导入System mscorlib,然后将System的{​​{1}}分配给Decimal

CommandParameter

这消除了在VM端转换数字类型所必需的。

答案 1 :(得分:1)

不是将ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader("PDF PATH"); PdfStamper stamper; stamper = new PdfStamper(reader, baos); AcroFields fields = stamper.getAcroFields(); TextField textField = new TextField(stamper.getWriter(), new Rectangle(18, 200, 380, 278), "newTextField"); textField.setOptions(TextField.MULTILINE); textField.setFontSize(0f); textField.setText("VERY LONG TEXT"); //textField.setOptions(TextField.READ_ONLY); If I add this option my textfield is no longer multiline stamper.addAnnotation(textField.getTextField(), 1); stamper.close(); 字面分配给5.00000,而是尝试将XAML中的值定义为资源(​​根据this topic)。您的XAML代码可能看起来像这样

CommandParameter

答案 2 :(得分:0)

您遇到的问题是,您指定了string&#34; 5&#34;到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作为string处理:

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
    }
}