Domanda

Voglio utilizzare una barra di scorrimento per modificare l'opacità di un modulo.

Questo è il mio codice:

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

Quando creo l'applicazione, dà il seguente errore:

Impossibile convertire implicitamente il tipo 'decimal' A 'double'.

Ho provato a usare trans E double ma poi il controllo non funziona.Questo codice ha funzionato correttamente in un progetto VB.NET precedente.

È stato utile?

Soluzione

Non è necessario un cast esplicito per raddoppiare in questo modo:

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

Identificando la costante come 5000.0 (o come 5000d) è sufficiente:

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

Altri suggerimenti

Una risposta più generica alla domanda generica "Decimale vs Doppio?": Decimale per i calcoli monetari per preservare la precisione, Doppio per calcoli scientifici che non risentono di piccole differenze.Poiché Double è un tipo nativo della CPU (la rappresentazione interna è archiviata in base 2), i calcoli effettuati con Double hanno prestazioni migliori di Decimal (che è rappresentato in base 10 internamente).

Il tuo codice ha funzionato bene in VB.NET perché esegue implicitamente qualsiasi cast, mentre C# ne ha sia impliciti che espliciti.

In C# la conversione da decimale a double è esplicita in quanto si perde precisione.Ad esempio, 1.1 non può essere espresso accuratamente come doppio, ma può essere espresso come decimale (vedi "Numeri in virgola mobile: più imprecisi di quanto pensi"per il motivo).

In VB la conversione è stata aggiunta per te dal compilatore:

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

Quello (double) deve essere dichiarato esplicitamente in C#, ma può esserlo implicito dal compilatore più "permissivo" di VB.

Perché dividi per 5000?Basta impostare i valori minimo e massimo della TrackBar tra 0 e 100 e quindi dividere il valore per 100 per la percentuale di opacità.L'esempio minimo di 20 seguenti impedisce al modulo di diventare completamente invisibile:

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

Hai due problemi.Primo, Opacity richiede un valore doppio, non decimale.Il compilatore ti sta dicendo che mentre esiste una conversione tra decimal e double, è una conversione esplicita che devi specificare affinché funzioni.Il secondo è quello TrackBar.Value è un valore intero e dividendo un int per un int si ottiene un int indipendentemente dal tipo di variabile a cui lo assegni.In questo caso c'è un cast implicito da int a decimal o double - perché non c'è perdita di precisione quando si esegue il cast - quindi il compilatore non si lamenta, ma il valore che ottieni è sempre 0, presumibilmente, poiché trackBar.Value è sempre inferiore a 5000.La soluzione è modificare il codice in modo che utilizzi double (il tipo nativo per Opacità) ed eseguire l'aritmetica in virgola mobile rendendo esplicitamente double la costante - che avrà l'effetto di promuovere l'aritmetica - o cast trackBar.Value raddoppiare, il che farà la stessa cosa - o entrambi.Oh, e non hai bisogno della variabile intermedia a meno che non venga utilizzata altrove.La mia ipotesi è che il compilatore lo ottimizzerebbe comunque.

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

A mio avviso è auspicabile essere il più espliciti possibile.Ciò aggiunge chiarezza al codice e aiuta i tuoi colleghi programmatori che potrebbero eventualmente leggerlo.

Oltre a (o invece di) aggiungere a .0 al numero che puoi utilizzare decimal.ToDouble().

Ecco alcuni esempi:

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

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

Suona come this.Opacity è un valore doppio e al compilatore non piace che tu provi a inserirvi un valore decimale.

Dovresti usare 5000.0 invece di 5000.

IL Opacità l'immobile è di doppia tipologia:

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

o semplicemente:

this.Opacity = trackBar1.Value / 5000.0;

O:

this.Opacity = trackBar1.Value / 5000d;

Nota che sto usando 5000.0 (O 5000d) per forzare una doppia divisione perché trackBar1.Value è un numero intero ed eseguirebbe una divisione intera e il risultato sarebbe un numero intero.

Supponendo che tu stia utilizzando WinForms, Form.Opacity è di tipo double, quindi dovresti usare:

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

A meno che non ti serva il valore altrove, è più semplice scrivere:

this.Opacity = trackBar1.Value / 5000.0;

Il motivo per cui il controllo non funziona quando hai modificato il codice in modo che fosse semplicemente un doppio era perché avevi:

double trans = trackbar1.Value / 5000;

che ha interpretato il 5000 come numero intero e perché trackbar1.Value è anche un numero intero your trans il valore era sempre zero.Rendendo esplicitamente il numerico un valore in virgola mobile aggiungendo il .0 il compilatore ora può interpretarlo come double ed eseguire il calcolo corretto.

La soluzione migliore è:

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

Da Opacity è un valore doppio, userei semplicemente un doppio fin dall'inizio e non lancerei affatto, ma assicurati di usare un doppio durante la divisione in modo da non perdere precisione

Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top