我想用 aTrack-Bar
来改变 aForm
的不透明度。
这是我的代码:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
当我构建应用程序时,它给出了以下错误:
Cannot implicitly convert type decimal to double
我曾尝试使用trans
and double
,但随后Control
不起作用。此代码在过去的 VB.NET 项目中运行良好。
我想用 aTrack-Bar
来改变 aForm
的不透明度。
这是我的代码:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
当我构建应用程序时,它给出了以下错误:
Cannot implicitly convert type decimal to double
我曾尝试使用trans
and double
,但随后Control
不起作用。此代码在过去的 VB.NET 项目中运行良好。
An explicit cast to double
like this isn't necessary:
double trans = (double) trackBar1.Value / 5000.0;
Identifying the constant as 5000.0
(or as 5000d
) is sufficient:
double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
通用问题“十进制与双倍?”的更通用答案:
十进制用于货币计算以保持精度。Double用于不受微小差异影响的科学计算。由于 Double 是 CPU 原生的类型(内部表示存储在base 2中),使用 Double 进行的计算比 Decimal 执行得更好(内部以10表示)。
您的代码在 VB.NET 中运行良好,因为它隐式执行任何强制转换,而 C# 具有隐式和显式强制转换。
在 C# 中,从十进制到双精度的转换是明确的,因为您会失去准确性。例如 1.1 不能准确地表示为双精度数,但可以表示为小数(原因请参阅“浮点数 - 比你想象的更不准确”)。
在 VB 中,编译器为您添加了转换:
decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;
这(double)
必须在 C# 中明确说明,但可以通过 VB 更“宽容”的编译器来暗示。
为什么要除以 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;
}
你有两个问题。
首先,Opacity
需要一个双精度值,而不是十进制值。编译器告诉您,虽然十进制和双精度之间存在转换,但您需要指定显式转换才能使其工作。
其次,TrackBar.Value
是一个整数值,并且将一个 int 除以一个 int 会得到一个 int,无论您将它分配给什么类型的变量。在这种情况下,存在从 int 到 decimal 或 double 的隐式转换,因为在进行转换时不会损失精度。所以编译器不会抱怨。但是你得到的值总是 0,大概是因为trackBar.Value
总是小于 5000。
解决方案是将代码更改为使用双精度(不透明度的本机类型)并通过显式将常量设为双精度来执行浮点运算,这将具有提升算术或强制转换trackBar.Value
为双精度的效果,这将做同样的事情或两者。您不需要中间变量,除非它在其他地方使用。我的猜测是编译器无论如何都会优化它。
trackBar.Opacity = (double)trackBar.Value / 5000.0;
在我看来,希望尽可能明确。这增加了代码的清晰度,并有助于最终可能阅读它的程序员伙伴。
除了(或代替)将 a 附加.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);
听起来像是this.Opacity
一个双精度值,编译器不喜欢您尝试将十进制值塞入其中。
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
它是一个整数,它将执行整数除法,结果将是一个整数。
您应该使用5000.0
而不是5000
.
假设您使用的是 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
编译器现在可以将其解释为双精度并执行正确的计算。
因为Opacity
是双精度值,所以我会从一开始就使用双精度,根本不强制转换,但一定要在除法时使用双精度,这样就不会失去任何精度
Opacity = trackBar1.Value / 5000.0;
最好的解决方案是:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);