#c# #wpf #validation #get #set
#c# #wpf #проверка #получить #установить
Вопрос:
Я пишу следующие get и set для проверки ввода из текстового поля. В основном предполагается, что это проверяет, ввел ли пользователь все значения. Когда я оставляю текстовые поля пустыми, это ничего не делает и показывает ‘0’ в выходных данных, где использовалась эта переменная. Однако он показывает сгенерированное системой исключение и останавливает выполнение, но мне интересно, почему он не проверяет входные данные через свойства?
Вот мой код:
public double RecoDoseSize
{
get
{
return recoDoseSize;
}
set
{
if (!(value>0))
{
MessageBox.Show("Please Enter the recommended dose size for this product");
textBox8.Focus();
}
recoDoseSize = value;
}
}
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
recoDoseSize = double.Parse(textBox8.Text);
NoOfDosespUnit = TotalContentProduct/recoDoseSize;
}
Комментарии:
1. Я не совсем понимаю пример кода. Является ли recoDoseSize тем же, что и RecoDoseSize, или это несвязанная частная переменная? Вы имеете в виду это.RecoDoseSize?
2. Причина, по которой вы получаете 0 в описанном вами случае, заключается в том, что ParseMethod делает все возможное для значения свойства Text по умолчанию в текстовом поле.
3. @dawebber: Поскольку средство получения RecoDoseSize возвращает recoDoseSize, я предполагаю, что они связаны. 😉
4. Вам нужно следить за тем, чтобы RecoDoseSize был равен 0 (нулю), чтобы избежать этого неприятного деления на ноль, в которое вы позволяете своему пользователю входить. Кроме того, я бы переименовал свойство в DoseSize или RecommendedDoseSize, если это находится в «общедоступной» библиотеке, которую может использовать кто-либо другой: что, черт возьми, такое «Reco», было бы моим первым вопросом.
5. @Heinzi—в этом примере кода есть о чем догадаться. Реальный смысл моего комментария состоял в том, чтобы продемонстрировать OP, что следует быть более конкретным с примерами кода. Хотя я бы согласился с вами, и это был будущий ответ: используйте свойство, а не private var.
Ответ №1:
Вы устанавливаете recoDoseSize
резервное поле, а не RecoDoseSize
свойство, в котором содержится ваш код. Таким образом, ваш код не выполняется. Вам нужно изменить вторую строку тела вашего метода на
RecoDoseSize = double.Parse(textBox8.Text);
(обратите внимание на заглавную R
).
Комментарии:
1. Еще один пример того, почему различие свойств и полей по регистру — плохая идея.
2. @Pondidum: Нет, это нормально работает (если вы, конечно, знаете, что делаете), хотя я все еще недавно переключился на подчеркнутые поля.
3. @Pond если вы не используете плохой шрифт (или, я думаю, у вас особенно плохое зрение), очень легко увидеть разницу между первыми буквами в верхнем и нижнем регистре. (Середина имени переменной a может быть более сложной, поскольку ваши глаза естественным образом не фокусируются так сильно, как на первой / последней букве)
4. Спасибо всем за помощь. Моя ошибка, я изменил его на RecoDoseSize, но он по-прежнему делает то же самое. При нажатии на кнопку выдается системная ошибка, но сообщение об ошибке никогда не отображается.:(
5. @Mango ошибка, которую вы получаете, вероятно, исходит от Parse, потому что не удалось преобразовать текст в допустимый
double
. ИспользуйтеTryParse
в моем ответе.
Ответ №2:
Другие дали правильный ответ на вопрос, как указано. А именно, что вы должны вызывать верхний регистр RecoDoseSize
, если вы хотите использовать средство получения / установки.
Однако показывать окно сообщения внутри установщика — крайне плохая практика, потому что это нарушает принцип наименьшего удивления.
Когда кто-то смотрит на строку RecoDoseSize = double.Parse(textBox8.Text);
, совсем не очевидно, что эта операция может привести к появлению окна сообщения.
Иногда бывают исключения, когда имеет смысл использовать установщик, вызывающий изменения пользовательского интерфейса (например, Visible
свойство в элементах управления), однако по умолчанию всегда должно быть не делать этого, если вы не уверены, что это будет более запутанным, если не делать этого (например, было бы удивительно, если бы вы установили, Visible = false
однако это все еще было видно).
Что касается вашего комментария о том, как вы должны это реализовать, проверка должна быть выполнена в обработчике щелчков, и свойство может быть просто автоматическим свойством, вот так:
public double RecoDoseSize { get; set; }
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
double enteredSize;
if (!double.TryParse(textBox8.Text, out enteredSize) || enteredSize <= 0)
{
MessageBox.Show("Please Enter the recommended dose size for this product");
textBox8.Focus();
return;
}
RecoDoseSize = enteredSize;
NoOfDosespUnit = TotalContentProduct / recoDoseSize;
}
Вы захотите использовать TryParse, потому что при синтаксическом анализе вы получите ошибку, если текст не является допустимым double
. Что делает TryParse, так это возвращает true
или false
в зависимости от того, удалось ли это, и он заполняет параметр out результатом, если это успешно.
Итак, что это делает, так это если либо не удалось проанализировать результат, либо в результате <= 0
отображается окно сообщения. В этом случае это также return
из метода, поэтому остальная его часть не выполняется. В качестве альтернативы остальная часть метода может находиться в else
блоке, и в этом случае return
он не нужен. Это зависит от стиля, какой способ предпочтительнее.
Комментарии:
1. Не могли бы вы сообщить мне, как еще я должен реализовать эту функциональность в своем коде? Я как бы учусь, выполняя здесь: (
2. @Mango вы также можете использовать
TryParse
дляtextBox7
тоже. Если вы используетеParse
вы говорите, что я точно знаю, что текст будет допустимымdouble
, просто проанализируйте его для меня. ИспользуйтеTryParse
, когда вы не уверены на 100%, что это будет допустимо. Вы также можете подумать о переименовании текстовых полей в нечто, представляющее то, что они содержат.
Ответ №3:
На самом деле вы никогда не используете средство получения / установки. Вы используете фактическое имя поля: recoDoseSize
напрямую. Измените его на RecoDoseSize
.
Ответ №4:
private void Submit2_Click(object sender, RoutedEventArgs e)
{
TotalContentProduct = double.Parse(textBox7.Text);
RecoDoseSize= double.Parse(textBox8.Text);
NoOfDosespUnit = TotalContentProduct/recoDoseSize;
}
Ответ №5:
Вы не должны обрабатывать фокус в своем операторе set.
Кроме того, вам нужно убедиться, что это значение не равно null, иначе вы не сможете сравнить его ни с чем (больше, чем и т.д.).
Комментарии:
1. свойство является a,
double
поэтомуvalue
также является (не обнуляемым) double. Это не будет null.2. Нижний регистр
double
никогда не может бытьnull
. Если только это не обнуляемый тип:double?