Я хочу использовать Track-Bar
для изменения непрозрачности Form
.
Это мой код:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
Когда я создаю приложение, выдает следующую ошибку:
Cannot implicitly convert type decimal to double
Я пробовал использовать trans
и double
, но тогда Control
не работает. Этот код отлично работал в прошлом проекте VB.NET.
Совершенно не по теме, но это первый вопрос о Stackoverflow, доступный для просмотра пользователям все. (Фактический первый может быть просмотрен пользователями с количеством представителей> 10 тыс.)
@TraumaPony, это trackbar
. Вряд ли когда-либо делалось использовать такое высокое значение на trackbar
.
Ух ты! Это первый вопрос, который еще не решен!
Явное приведение к double
не требуется:
double trans = (double) trackBar1.Value / 5000.0;
Достаточно указать константу как 5000.0
(или как 5000d
):
double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
Похоже, this.Opacity
- это двойное значение, и компилятору не нравится, когда вы пытаетесь втиснуть в него десятичное значение.
Более общий ответ на общий вопрос «Десятичное или двойное?»:
Десятичный предназначен для денежных расчетов с целью сохранения точности. Двойной предназначен для научных расчетов, на которые не влияют небольшие различия. Поскольку Double - это тип, который является собственным для ЦП (внутреннее представление хранится в база 2), вычисления, выполненные с помощью Double, выполняются лучше, чем Decimal (который внутренне представлен в база 10).
На мой взгляд, желательно быть как можно более явным. Это добавляет ясности коду и помогает вашим коллегам-программистам, которые со временем могут его прочитать.
В дополнение к (или вместо) добавления .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);
Ваш код отлично работал в 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;
}
Разве это не решило бы проблему? Вместо проблемы с 5000
, у OP будет проблема с 100
?
Вы должны использовать 5000.0
вместо 5000
.
У вас две проблемы.
Во-первых, Opacity
требует двойного, а не десятичного значения. Компилятор сообщает вам, что, хотя существует преобразование между десятичным и двойным числом, это явное преобразование, которое вам необходимо указать, чтобы оно работало.
Во-вторых, TrackBar.Value
- это целочисленное значение, и деление int на int приводит к int независимо от того, какой тип переменной вы его назначаете. В этом случае происходит неявное приведение типа int к decimal или double, потому что при приведении нет потери точности. Так что компилятор не жалуется. Но значение, которое вы получаете, по-видимому, всегда равно 0, поскольку trackBar.Value
всегда меньше 5000.
Решение состоит в том, чтобы изменить ваш код, чтобы использовать double (собственный тип для Opacity) и выполнять арифметику с плавающей запятой, явно сделав константу двойной, что приведет к повышению арифметики или приведению trackBar.Value
к удвоению, что будет делать то же самое. вещь или оба. Вам не нужна промежуточная переменная, если она не используется где-либо еще. Я предполагаю, что компилятор все равно оптимизирует его.
trackBar.Opacity = (double)trackBar.Value / 5000.0;
Свойство Непрозрачность имеет двойной тип:
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;
Попробуйте использовать функцию приведения:
this.Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);
Объяснение было бы порядком. Например, в чем идея / суть?
Кроме того, Decimal не может представлять такое же широкое значение, как Double. Десятичное число может увеличиваться только до +/- 7,9228162514264337593543950335E + 28; в то время как Double может подняться до +/- 1,79769313486232E + 308