У меня была та же проблема, что и у этого, и натолкнулся на это решение изменения .cs, сгенерированного xsd.exe. Хотя это действительно сработало, мне было неудобно изменять сгенерированный код, так как мне нужно было бы это делать, когда я восстанавливал классы. Это также привело к некоторому неудобному коду, который должен был протестировать и передать в XmlNode [] для элементов mailto.
Моим решением было переосмыслить xsd. Я отбросил использование смешанного типа и по существу определил свой собственный смешанный тип.
У меня было это
XML: <text>some text <mailto>me@email.com</mailto>some more text</text>
<xs:complexType name="text" mixed="true">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="mailto" type="xs:string" />
</xs:sequence>
</xs:complexType>
и изменено на
XML: <mytext><text>some text </text><mailto>me@email.com</mailto><text>some more text</text></mytext>
<xs:complexType name="mytext">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="text">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="mailto">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string" />
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
Мой сгенерированный код теперь дает мне класс myText:
public partial class myText{
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("mailto", typeof(myTextTextMailto))]
[System.Xml.Serialization.XmlElementAttribute("text", typeof(myTextText))]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
порядок элементов теперь сохраняется в сериализации / десериализации, но мне нужно проверить / cast to / program на типы myTextTextMailto
и myTextText
.
Просто подумал, что я брошу это как альтернативный подход, который работал для меня.
Две опции:
Использование NumericUpDown
вместо этого. NumericUpDown делает фильтрацию для Вас, которая хороша. Конечно, это также дает Вашим пользователям способность поразить стрелки вверх и вниз в клавиатуру, чтобы увеличить и постепенно уменьшить текущее значение.
Дескриптор соответствующие события клавиатуры для предотвращения чего-либо кроме числового входа. Я имел успех с этим два обработчика событий на стандартном TextBox:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
(e.KeyChar != '.'))
{
e.Handled = true;
}
// only allow one decimal point
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
{
e.Handled = true;
}
}
можно удалить проверку на '.'
(и последующая проверка на больше чем один '.'
), если TextBox не должен позволять десятичные разряды. Вы могли также добавить проверку на '-'
, если Ваш TextBox должен позволить отрицательные величины.
, Если Вы хотите ограничить пользователя для количества цифры, используйте: textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits
Я принимаю от контекста и тегов, Вы использовали это, Вы пишете.NET приложение C#. В этом случае можно подписаться на измененное событие текста, и проверять каждое нажатие клавиши.
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text, "[^0-9]"))
{
MessageBox.Show("Please enter only numbers.");
textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
}
}
Попробуйте MaskedTextBox. Это берет простой формат маски, таким образом, можно ограничить вход числами или датами или что бы то ни было.
Вы могли использовать событие TextChanged / Keypress, использовать regex, чтобы отфильтровать на числах и принять некоторые меры.
И просто потому что это всегда - больше забавы сделать материал в одной строке...
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
}
ПРИМЕЧАНИЕ: Это НЕ препятствует пользователю Копия / Вставка в это текстовое поле. Это не сбой безопасный способ санировать Ваши данные.
Смотрите на Входная обработка в WinForm
, я отправил свое решение, которое использует события ProcessCmdKey и OnKeyPress на текстовом поле. Комментарии показывают Вам, как использовать Regex, чтобы проверить нажатие клавиши и блокировать/позволять соответственно.
Я сделал что-то для этого на CodePlex.
Это работает путем прерывания события TextChanged. Если результатом будет большое количество, то он будет сохранен. Если это будет что-то не так, последнее хорошее значение будет восстановлено. Источник является немного слишком большим для публикации здесь, но вот ссылка на класс , который обрабатывает ядро этой логики.
Рабочее решение для WPF & простое TextChangedEventArgs
.
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
var TextBox = (sender as TextBox);
// if not a numeric value, remove news characters
if (Regex.IsMatch(TextBox.Text, "[^0-9]"))
{
foreach (TextChange Change in e.Changes)
{
TextBox.Text = TextBox.Text.Remove(Change.Offset, Change.AddedLength);
TextBox.CaretIndex = Change.Offset;
}
}
}