Frage

Ich möchte eine Track-Leiste verwenden, um die Deckkraft eines Formulars zu ändern.

Das ist mein Code:

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

Wenn ich die Anwendung erstelle, wird die folgende Fehlermeldung angezeigt:

Der Typ kann nicht implizit konvertiert werden 'decimal' Zu 'double'.

Ich habe es mit versucht trans Und double aber dann funktioniert die Steuerung nicht.Dieser Code hat in einem früheren VB.NET-Projekt gut funktioniert.

War es hilfreich?

Lösung

Eine explizite Umwandlung in eine Verdoppelung wie diese ist nicht erforderlich:

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

Identifizieren der Konstante als 5000.0 (oder wie 5000d) ist ausreichend:

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

Andere Tipps

Eine allgemeinere Antwort auf die allgemeine Frage „Dezimal vs. Doppelt?“: Dezimal für monetäre Berechnungen zur Wahrung der Präzision, Doppelt für wissenschaftliche Berechnungen, die nicht durch kleine Unterschiede beeinträchtigt werden.Da Double ein für die CPU nativer Typ ist (die interne Darstellung wird in gespeichert). Basis 2), sind Berechnungen mit Double besser als mit Decimal (dargestellt in). Basis 10 im Inneren).

Ihr Code hat in VB.NET gut funktioniert, da er alle Umwandlungen implizit durchführt, während C# sowohl implizite als auch explizite Umwandlungen hat.

In C# erfolgt die Konvertierung von Dezimalzahl in Doppelzahl explizit, da dadurch die Genauigkeit verloren geht.Beispielsweise kann 1,1 nicht genau als Doppelzahl ausgedrückt werden, wohl aber als Dezimalzahl (siehe „Gleitkommazahlen – ungenauer als Sie denken"aus dem Grund warum).

In VB wurde die Konvertierung vom Compiler für Sie hinzugefügt:

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

Das (double) muss in C# explizit angegeben werden, kann aber sein impliziert durch den „nachsichtigeren“ Compiler von VB.

Warum dividieren Sie durch 5000?Stellen Sie einfach die Minimal- und Maximalwerte der TrackBar zwischen 0 und 100 ein und dividieren Sie dann den Wert durch 100, um den Prozentsatz der Deckkraft zu erhalten.Das folgende Beispiel mit mindestens 20 verhindert, dass das Formular vollständig unsichtbar wird:

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

Sie haben zwei Probleme.Erste, Opacity erfordert einen Doppel- und keinen Dezimalwert.Der Compiler teilt Ihnen mit, dass es zwar eine Konvertierung zwischen Dezimalzahl und Doppelzahl gibt, es sich jedoch um eine explizite Konvertierung handelt, die Sie angeben müssen, damit sie funktioniert.Das zweite ist das TrackBar.Value ist ein ganzzahliger Wert und die Division eines Ganzzahlwerts durch einen Ganzzahlwert ergibt einen Ganzzahlwert, unabhängig davon, welcher Art von Variable Sie ihn zuweisen.In diesem Fall gibt es eine implizite Umwandlung von int nach decimal oder double – da bei der Umwandlung kein Präzisionsverlust auftritt – der Compiler beschwert sich also nicht, aber der Wert, den Sie erhalten, ist vermutlich immer 0, da trackBar.Value ist immer kleiner als 5000.Die Lösung besteht darin, Ihren Code so zu ändern, dass er double (den nativen Typ für Opacity) verwendet und Gleitkomma-Arithmetik durchführt, indem Sie die Konstante explizit zu einem Double machen – was den Effekt hat, dass die Arithmetik gefördert wird – oder das Casting trackBar.Value verdoppeln, was dasselbe bewirkt – oder beides.Oh, und Sie brauchen die Zwischenvariable nicht, es sei denn, sie wird an anderer Stelle verwendet.Ich vermute, dass der Compiler es sowieso wegoptimieren würde.

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

Meiner Meinung nach ist es wünschenswert, so explizit wie möglich zu sein.Dies erhöht die Klarheit des Codes und hilft Ihren Programmierkollegen, die ihn möglicherweise später lesen.

Zusätzlich (oder anstelle) des Anhängens von a .0 zu der Nummer können Sie verwenden decimal.ToDouble().

Hier sind einige Beispiele:

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

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

Das klingt nach this.Opacity ist ein Double-Wert, und der Compiler mag es nicht, wenn Sie versuchen, einen Dezimalwert hineinzuzwingen.

Du solltest benutzen 5000.0 anstatt 5000.

Der Opazität Die Eigenschaft ist vom Typ double:

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

oder einfach:

this.Opacity = trackBar1.Value / 5000.0;

oder:

this.Opacity = trackBar1.Value / 5000d;

Beachten Sie, dass ich verwende 5000.0 (oder 5000d), um eine doppelte Division zu erzwingen, weil trackBar1.Value ist eine ganze Zahl und es würde eine ganzzahlige Division durchführen und das Ergebnis wäre eine ganze Zahl.

Angenommen, Sie verwenden WinForms, Form.Opacity ist vom Typ double, also sollten Sie Folgendes verwenden:

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

Sofern Sie den Wert nicht woanders benötigen, ist es einfacher zu schreiben:

this.Opacity = trackBar1.Value / 5000.0;

Der Grund, warum das Steuerelement nicht funktionierte, als Sie Ihren Code so geändert haben, dass er einfach ein Double ist, liegt darin, dass Sie Folgendes hatten:

double trans = trackbar1.Value / 5000;

welches das interpretierte 5000 als ganze Zahl, und weil trackbar1.Value ist auch eine Ganzzahl your trans Der Wert war immer Null.Indem Sie die Zahl explizit zu einem Gleitkommawert machen, indem Sie hinzufügen .0 Der Compiler kann es nun als Double interpretieren und die richtige Berechnung durchführen.

Die beste Lösung ist:

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

Seit Opacity ein Double-Wert ist, würde ich von Anfang an einfach ein Double verwenden und überhaupt nicht umwandeln, aber stellen Sie sicher, dass Sie beim Teilen ein Double verwenden, damit Sie nicht an Präzision verlieren

Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top