我想使用轨迹栏来改变窗体的不透明度。
这是我的代码:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
当我构建应用程序时,它会出现以下错误:
无法将
'decimal'
类型隐式转换为'double'
。
我尝试使用trans
和double
但是控件不起作用。这段代码在过去的VB.NET项目中运行良好。
答案 0 :(得分:420)
没有必要像这样加倍显式演员:
double trans = (double) trackBar1.Value / 5000.0;
将常量标识为5000.0
(或5000d
)就足够了:
double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
答案 1 :(得分:120)
通用问题“Decimal vs Double?”的更通用的答案: Decimal 用于货币计算以保持精度, Double 用于不受影响的科学计算差异很小。由于Double是CPU的原生类型(内部表示存储在 base 2 中),因此使用Double执行的计算优于Decimal(在 base 10 中表示)内部)。
答案 2 :(得分:80)
您的代码在VB.NET中运行良好,因为它隐式执行任何强制转换,而C#同时具有隐式和显式。
在C#中,当你失去准确性时,从十进制到双倍的转换是明确的。例如1.1不能准确地表示为double,但可以作为小数(见“Floating point numbers - more inaccurate than you think”的原因)。
在VB中,编译器为您添加了转换:
decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;
必须在C#中明确声明(double)
,但VB的“宽容”编译器可以暗示。
答案 3 :(得分:77)
你为什么要除以5000?只需将TrackBar的最小值和最大值设置在0到100之间,然后将值除以100以获得不透明度百分比。下面的最小20个示例可以防止表单变得完全不可见:
private void Form1_Load(object sender, System.EventArgs e)
{
TrackBar1.Minimum = 20;
TrackBar1.Maximum = 100;
TrackBar1.LargeChange = 10;
TrackBar1.SmallChange = 1;
TrackBar1.TickFrequency = 5;
}
private void TrackBar1_Scroll(object sender, System.EventArgs e)
{
this.Opacity = TrackBar1.Value / 100;
}
答案 4 :(得分:60)
你有两个问题。首先,Opacity
需要一个double,而不是十进制值。编译器告诉您,虽然十进制和双精度之间存在转换,但它是一个显式转换,您需要指定它才能使其工作。第二个是TrackBar.Value
是一个整数值,将int除以int会产生一个int,无论你指定什么类型的变量。在这种情况下,存在从int到decimal或double的隐式转换 - 因为在执行转换时没有精度损失 - 所以编译器不会抱怨,但是你得到的值总是0,大概是因为{{ 1}}总是小于5000.解决方案是将代码更改为使用double(Opacity的本机类型)并通过显式使常量变为double来执行浮点运算 - 这将具有促进算术的效果 - 或者将trackBar.Value
转换为double,这将执行相同的操作 - 或两者兼而有之。哦,除非在别处使用,否则你不需要中间变量。无论如何,我的猜测是编译器会优化它。
trackBar.Value
答案 5 :(得分:57)
在我看来,希望尽可能明确。这增加了代码的清晰度,并帮助最终可能阅读它的程序员。
除了(或代替)在号码上附加.0
之外,您还可以使用decimal.ToDouble()
。
以下是一些例子:
// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);
// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
答案 6 :(得分:55)
听起来this.Opacity
是一个双精度值,编译器不喜欢你试图将十进制值加入其中。
答案 7 :(得分:47)
您应该使用5000.0
代替5000
。
答案 8 :(得分:45)
Opacity属性是双重类型:
double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;
或简单地说:
this.Opacity = trackBar1.Value / 5000.0;
或:
this.Opacity = trackBar1.Value / 5000d;
请注意,我使用5000.0
(或5000d
)来强制进行双重除法,因为trackBar1.Value
是一个整数,它将执行整数除法,结果将是一个整数。
答案 9 :(得分:45)
假设您使用的是WinForms,Form.Opacity
的类型为double
,那么您应该使用:
double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;
除非你需要其他地方的值,否则写起来更简单:
this.Opacity = trackBar1.Value / 5000.0;
当您将代码更改为双精度时控件不起作用的原因是因为您有:
double trans = trackbar1.Value / 5000;
将5000
解释为整数,并且因为trackbar1.Value
也是一个整数,所以trans
值始终为零。通过添加.0
显式地使数字成为浮点值,编译器现在可以将其解释为double并执行正确的计算。
答案 10 :(得分:39)
最佳解决方案是:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
答案 11 :(得分:39)
由于Opacity
是一个双精度值,我只是从一开始就使用双精度而根本不使用双精度值,但一定要在分割时使用双精度,这样你就不会失去任何精度
Opacity = trackBar1.Value / 5000.0;
答案 12 :(得分:33)
this.Opacity = trackBar1.Value / 5000d;
答案 13 :(得分:3)
尝试一下:
this.Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);
答案 14 :(得分:-1)
我们可以做这样的事情:
double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;
或简化为:
this.Opacity = trackBar1.Value / 5000.0;
您还可以使用内置的转换功能,例如Decimal.ToDouble()
:
double trans = trackBar1.Value / 5000.0;
this.Opacity = Decimal.ToDouble(trans);
您也可以使用简化形式,但是我不建议此时使用ToDouble()
。