【问题标题】:How do I pass decimal value as CommandParameter for a command using WPF?如何为使用 WPF 的命令传递十进制值作为 CommandParameter?
【发布时间】:2018-05-09 01:11:27
【问题描述】:

我有一个在 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.

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

【问题讨论】:

    标签: c# wpf xaml binding prism


    【解决方案1】:

    在 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.xml 中明确指定类型为 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>
    

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

    【讨论】:

      【解决方案2】:

      不要将5.00000 直接分配给CommandParameter,而是尝试将XAML 中的值定义为资源(​​根据this topic)。您的 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>
      

      【讨论】:

        【解决方案3】:

        您遇到的问题是,您将string“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 处理为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
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-11-05
          • 2010-10-12
          • 1970-01-01
          • 2012-09-04
          • 1970-01-01
          • 2014-03-23
          • 2017-10-21
          • 2011-01-20
          相关资源
          最近更新 更多