Вопрос

Я хочу использовать панель отслеживания, чтобы изменить непрозрачность формы.

Это мой код:

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

Когда я создаю приложение, оно выдает следующую ошибку:

Невозможно неявно преобразовать тип 'decimal' к 'double'.

Я попробовал использовать trans и double но тогда управление не работает.Этот код отлично работал в прошлом проекте VB.NET.

Это было полезно?

Решение

Явное приведение к удвоению не требуется:

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

Определение константы как 5000.0 (или как 5000d) достаточно:

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

Другие советы

Более общий ответ на общий вопрос «Десятичный или двойной?»: Десятичная дробь для денежных расчетов, чтобы сохранить точность, Двойной для научных расчетов, на которые не влияют небольшие различия.Поскольку Double — это тип, который является собственным для ЦП (внутреннее представление хранится в база 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 к десятичному или двойному - потому что при приведении не происходит потери точности - поэтому компилятор не жалуется, но получаемое вами значение всегда предположительно равно 0, поскольку trackBar.Value всегда меньше 5000.Решение состоит в том, чтобы изменить ваш код, чтобы использовать double (собственный тип для непрозрачности) и выполнять арифметику с плавающей запятой, явно делая константу двойной - что будет иметь эффект продвижения арифметики - или приведения trackBar.Value удвоить, что сделает то же самое - или и то, и другое.Да, и вам не нужна промежуточная переменная, если она не используется где-либо еще.Я предполагаю, что компилятор в любом случае оптимизирует его.

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

На мой взгляд, желательно быть как можно более откровенным.Это добавляет ясности коду и помогает вашим коллегам-программистам, которые в конечном итоге смогут его прочитать.

В дополнение (или вместо) добавления .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 — это двойное значение, и компилятору не нравится, когда вы пытаетесь втиснуть в него десятичное значение.

Вы должны использовать 5000.0 вместо 5000.

А Непрозрачность имущество имеет двойной тип:

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 является целым числом, и оно будет выполнять целочисленное деление, и результат будет целым числом.

Предполагая, что вы используете 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 компилятор теперь может интерпретировать его как двойное и выполнить правильные вычисления.

Лучшее решение:

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

С Opacity - это двойное значение, я бы просто использовал двойное значение с самого начала и вообще не приводил его, но обязательно используйте двойное значение при делении, чтобы не потерять точность

Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top