Pregunta

Quiero usar una barra de seguimiento para cambiar la opacidad de un formulario.

Este es mi código:

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

Cuando construyo la aplicación, me da el siguiente error:

No se puede convertir implícitamente el tipo 'decimal' a 'double'.

Intenté usar trans y double pero luego el control no funciona.Este código funcionó bien en un proyecto VB.NET anterior.

¿Fue útil?

Solución

No es necesario un elenco explícito para duplicar así:

double trans = (double) trackBar1.Value / 5000.0;

Identificando la constante como 5000.0 (o como 5000d) es suficiente:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

Otros consejos

Una respuesta más genérica para la pregunta genérica "¿Decimal vs Doble?": Decimal para cálculos monetarios para preservar la precisión, Doble para cálculos científicos que no se vean afectados por pequeñas diferencias.Dado que Double es un tipo nativo de la CPU (la representación interna se almacena en base 2), los cálculos realizados con Double funcionan mejor que con Decimal (que se representa en base 10 internamente).

Su código funcionó bien en VB.NET porque implícitamente realiza conversiones, mientras que C# tiene conversiones tanto implícitas como explícitas.

En C# la conversión de decimal a doble es explícita ya que se pierde precisión.Por ejemplo, 1.1 no se puede expresar con precisión como un doble, pero sí como un decimal (consulte "Números de coma flotante: más inexactos de lo que piensas"por la razón).

En VB, el compilador agregó la conversión:

decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;

Eso (double) tiene que indicarse explícitamente en C#, pero puede ser implícito por el compilador más "indulgente" de VB.

¿Por qué divides entre 5000?Simplemente establezca los valores Mínimo y Máximo de TrackBar entre 0 y 100 y luego divida el Valor por 100 para obtener el porcentaje de Opacidad.El ejemplo mínimo de 20 a continuación evita que el formulario se vuelva completamente invisible:

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

Tienes dos problemas.Primero, Opacity requiere un valor doble, no decimal.El compilador le dice que si bien hay una conversión entre decimal y doble, es una conversión explícita que debe especificar para que funcione.El segundo es que TrackBar.Value es un valor entero y dividir un int por un int da como resultado un int sin importar a qué tipo de variable se lo asigne.En este caso hay una conversión implícita de int a decimal o double, porque no hay pérdida de precisión cuando se realiza la conversión, por lo que el compilador no se queja, pero el valor que se obtiene siempre es 0, presumiblemente, ya que trackBar.Value siempre es menor que 5000.La solución es cambiar su código para usar doble (el tipo nativo para Opacidad) y hacer aritmética de punto flotante haciendo explícitamente que la constante sea doble, lo que tendrá el efecto de promover la aritmética, o convertir trackBar.Value duplicar, lo que hará lo mismo, o ambas cosas.Ah, y no necesitas la variable intermedia a menos que se use en otro lugar.Supongo que el compilador lo optimizaría de todos modos.

trackBar.Opacity = (double)trackBar.Value / 5000.0;

En mi opinión, sería deseable ser lo más explícito posible.Esto añade claridad al código y ayuda a sus compañeros programadores que eventualmente podrán leerlo.

Además de (o en lugar de) agregar un .0 al número, puedes usar decimal.ToDouble().

Aquí hay unos ejemplos:

// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

Suena como this.Opacity es un valor doble, y al compilador no le gusta que intentes meterle un valor decimal.

Deberías usar 5000.0 en lugar de 5000.

El Opacidad La propiedad es de doble tipo:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

o simplemente:

this.Opacity = trackBar1.Value / 5000.0;

o:

this.Opacity = trackBar1.Value / 5000d;

Note que estoy usando 5000.0 (o 5000d) para forzar una doble división porque trackBar1.Value es un número entero y realizaría una división de números enteros y el resultado sería un número entero.

Suponiendo que esté utilizando WinForms, Form.Opacity es de tipo double, entonces deberías usar:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

A menos que necesite el valor en otro lugar, es más sencillo escribir:

this.Opacity = trackBar1.Value / 5000.0;

La razón por la que el control no funciona cuando cambiaste tu código para que fuera simplemente doble fue porque tenías:

double trans = trackbar1.Value / 5000;

que interpretó el 5000 como un número entero, y porque trackbar1.Value también es un número entero tu trans El valor siempre fue cero.Al convertir explícitamente el valor numérico en punto flotante sumando el .0 el compilador ahora puede interpretarlo como doble y realizar el cálculo adecuado.

La mejor solución es:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

Desde Opacity es un valor doble, yo simplemente usaría un doble desde el principio y no lo lanzaría en absoluto, pero asegúrese de usar un doble al dividir para no perder precisión.

Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top