textbox validated method does not work while assigning value to textbox - winforms

I am using c#.net 2.0 winforms. I use errorprovider control in my form to validate a textbox. While I programatically assign value to that textbox. textbox validated method does not take the value from the textbox or considers it a blank value. How can I validate my textbox by without entering value in the textbox. Here is the code
private void textBox6_Validated(object sender, EventArgs e)
{
bTest6 = txtRegExPinIsValid(textBox6.Text);
if (bTest6)
{
this.errorProvider1.SetError(textBox6, "");
}
else
{
this.errorProvider1.SetError(textBox6, "This field must contain Exactly 6 digits");
}
}
private bool txtRegExPinIsValid(string textToValidate)
{
Regex TheRegExpression;
string TheTextToValidate;
string TheRegExTest = #"^\d{6}$";
TheTextToValidate = textToValidate;
TheRegExpression = new Regex(TheRegExTest);
// test text with expression
if (TheRegExpression.IsMatch(TheTextToValidate))
{
return true;
}
else
{
return false;
}
}
While performing update operation I fill the textbox with values from the ms access table. If the value is correct, just leave it otherwise I have to update it. Please help me. Thanks in advance

I would recommend placing the validation code in a separate method. Call that method from both the Validated event and the location in your code where you need to programatically validate, as shown below:
// Call this from wherever you need to validate a TextBox
void PerformValidation(TextBox textBox)
{
bTest6 = txtRegExPinIsValid(textBox6.Text);
if (bTest6)
{
this.errorProvider1.SetError(textBox6, "");
}
else
{
this.errorProvider1.SetError(textBox6, "This field must contain Exactly 6 digits");
}
}
private void textBox6_Validated(object sender, EventArgs e)
{
PerformValidation(textBox6);
}

Related

Scrolling in Sticky Notes

I got the following sticky note example:
If the sticky note has more than 9 rows, the additional rows are not visible.
I'm able to navigate through the note with my arrow keys. If I'm going to scroll with the mouse wheel, it seems to ignore the popup and just changes the page.
Is it possible to activate scrolling for sticky note popups?
Edit:The solution outlined below will soon be available as part of the samples included in the PDFTron SDK download. In the meanwhile, I hope that the below solution helps.
Yes, it is possible to activate scrolling for sticky notes.
The problem is most apparent when using the single page view. It appears to work as expected in continuous mode.
However it is not as simple as setting VerticalScrollVisibility = ScrollBarVisibility.Auto;. There are a few files that need to be modified to get this working.
The good news is that we can get the expected behaviour by modifying the code in the provided samples.
Solution
The solution is to add some handling for the PreviewMouseWheel event coming from the PDFViewWPF class.
In the downloaded samples, the following changes were made to get things running as expected:
Add a method to handle the PreviewMouseWheel event in the NoteHost class (Samples/PDFViewWPFTools/CS/Utilities/NoteHost.cs)
internal void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
var originalSource = (UIElement)e.OriginalSource;
if (originalSource.IsDescendantOf(mNoteBorder) && mTextBox.IsFocused)
{
mTextBox.ScrollToVerticalOffset(mTextBox.VerticalOffset - e.Delta);
e.Handled = true;
}
}
Also make sure to add mTextBox.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; in the NoteHost.CreateNoteAndArrow() method, after the mTextBox object is instantiated (~line 183).
Next, edit the NoteManager class - Samples/PDFViewWPFTools/CS/Utilities/NoteManager.cs - and add a HandlePreviewMouseWheel method. This will internally call the HandlePreviewMouseWheel on each displayed (opened) note and break at the first one where the event gets handled.
internal void HandlePreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
foreach(var note in mActiveNotes)
{
note.Value.HandlePreviewMouseWheel(sender, e);
if(e.Handled)
{
break;
}
}
}
Next, edit the ToolManager class to ensure that the note manager gets a chance to handle the PreviewMouseWheel before attempting a page change. Open Samples/PDFViewWPFTools/CS/ToolManager.cs and navigate to the PDFView_PreviewMouseWheel. The existing method should look like this:
private void PDFView_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
if (mCurrentTool != null && _IsEnabled)
{
ToolManager.ToolType prev_tm = mCurrentTool.ToolMode;
ToolManager.ToolType next_tm;
while (true)
{
mCurrentTool.PreviewMouseWheelHandler(sender, e);
next_tm = mCurrentTool.NextToolMode;
if (prev_tm != next_tm)
{
mCurrentTool = CreateTool(next_tm, mCurrentTool);
prev_tm = next_tm;
}
else
{
break;
}
}
}
}
Replace it with the below code:
private void PDFView_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
if (mCurrentTool != null && _IsEnabled)
{
ToolManager.ToolType prev_tm = mCurrentTool.ToolMode;
ToolManager.ToolType next_tm;
while (true)
{
mNoteManager.HandlePreviewMouseWheel(sender, e);
if (!e.Handled)
{
mCurrentTool.PreviewMouseWheelHandler(sender, e);
next_tm = mCurrentTool.NextToolMode;
if (prev_tm != next_tm)
{
mCurrentTool = CreateTool(next_tm, mCurrentTool);
prev_tm = next_tm;
}
else
{
break;
}
}
else
{
break;
}
}
}
}
By doing the above, we are giving the NoteManager a chance to handle the PreviewMouseWheel before doing anything else with it.
Another point to note is that we have to now "do the scrolling" in code, using the mTextBox.ScrollToVerticalOffset method in the NoteHost class.

Interact with the Ok/Accept Or Cancel Button of a RepositoryItemTimeSpanEdit?

as seen in this post, I need to interact with the button, I mean, save the value of the repository when the user press the OK button, any suggest?
You need to find your TimeSpanEdit control inside of the popup form. You can iterate through popupForm.Controls collection to find out the control with TimeSpanEdit type. Here is example of how to do it. After that you can use TimeSpanEdit.TimeSpan property to get the value of TimeSpanEdit control.
private void OkButton_Click(object sender, EventArgs e)
{
var popupForm = (TimeSpanEditDropDownForm)OwnedForms.FirstOrDefault(item => item is TimeSpanEditDropDownForm);
if (popupForm == null)
return;
var timeSpanEdit = GetAll(this, typeof(TimeSpanEdit)).FirstOrDefault();
if (timeSpanEdit == null)
return;
MessageBox.Show(timeSpanEdit.TimeSpan.ToString());
}
public IEnumerable<Control> GetAll(Control control,Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl,type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
I think you can use object sender. sender will contains probably TimeSpanEditDropDownForm and there you should get actual value of this form. :)
I presume this code is called from controller is it?
if it is true than you have View.CurrentObject and you must know which property uses this TimeSpanEditDropDownForm so you could do something like this.
private void OkButton_Click(object sender, EventArgs e)
{
MyClass myClass = View.CUrrentObject as MyClass;
TimeSpanEditDropDownForm timeSpanForm = sender as TimeSpanEditDropDownForm;
myClass.CurrentTime = timeSpanForm.CurrentTime;
myClass.Session.CommitChanges();
MessageBox.Show("Ok");
}
I dont know what is name of right attribute wich store TimeSpan inside TimeSpanEditDropDownForm thats thing you must find out but I think it could helps :)

How to make TextBox style in XAML so that TextBox accepts only numbers

I want to create Style for TextBox so that it only accepts numbers and no characters or special symbols.
Currently I am doing it with the help of back code (in C#) like:
Regex regex = new Regex("[^0-9]+");
e.Handled = regex.IsMatch(e.Text);
Is it possible to make XAML style for handling this scenario?
It's not really possible with XAML only. In my experience, the best thing to do is to derive from TextBox, add handlers to anything that could input text, and then validate the text as it comes in. Either reject the change by handling the event, or accept it by letting the routed event propogate.
A general base class would look like:
public abstract class RestrictedTextBox : TextBox
{
protected RestrictedTextBox()
{
PreviewTextInput += RestrictedTextBox_PreviewTextInput;
}
protected abstract bool IsValid(string proposed);
private void RestrictedTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string proposed = GetProposedText(e.Text);
if (!IsValid(proposed))
e.Handled = true;
}
private string GetProposedText(string newText)
{
var text = this.Text;
if (SelectionStart != -1)
text.Remove(this.SelectionStart, this.SelectionLength);
return text.Insert(this.CaretIndex, newText);
}
}
To create a concrete instance for, let's say, a DoubleTextBox, you can easily do:
public class DoubleTextBox : RestrictedTextBox
{
protected override bool IsValid(string proposed)
{
double throwAwayDouble;
return double.TryParse(proposed, out throwAwayDouble);
}
}
This will only allow you to input text that successfully parses to a double. I'll leave it to you to handle the keydown-event (for spacebar) and the paste-event

Restrict text input inside combobox

I need to restrict text input inside combobox with positive numbers. I've searched stackoverflow for this and found similar question: Recommended way to restrict input in JavaFX textfield
The only difference is that the mentioned question addresses bare textfield. The answer approved by the javafx designers is to extend the TextField class and override couple of methods: replaceText and replaceSelection. This hack does not work with combobox: TextField instance if stored inside and is avaiable as read-only property named editor.
So what is the recommended way to restrict text input inside javafx combobox?
Since this question question never got a proper answer I'm adding a solution I've implemented that restricts the user to input that matches a regular expression and is shorter than a particular length (this is optional). This is done by adding a ChangeListener to the editor TextField. Any input that doesn't match will not get written into the editor TextField.
This example restricts the user to a maximum of two numeric characters.
ComboBox<Integer> integerComboBox = new ComboBox<Integer>();
integerComboBox.setEditable(true);
integerComboBox.getEditor().textProperty()
.addListener(new ChangeListener<String>() {
// The max length of the input
int maxLength = 2;
// The regular expression controlling the input, in this case we only allow number 0 to 9.
String restriction = "[0-9]";
private boolean ignore;
#Override
public void changed(
ObservableValue<? extends String> observableValue,
String oldValue, String newValue) {
if (ignore || newValue == null) {
return;
}
if (newValue.length() > maxLength) {
ignore = true;
integerComboBox.getEditor().setText(
newValue.substring(0, maxLength));
ignore = false;
}
if (!newValue.matches(restriction + "*")) {
ignore = true;
integerComboBox.getEditor().setText(oldValue);
ignore = false;
}
}
});
You might register a check method on the editor property to check if any input is accpetable.
Here I allow editing, but draw a red frame if values are not in the items list.
ObservableList<String> myChoices = FXCollections.observableArrayList();
void testComboBoxCheck(VBox box) {
myChoices.add("A");
myChoices.add("B");
myChoices.add("C");
ComboBox<String> first = new ComboBox<String>();
first.setItems(myChoices);
first.setEditable(true);
first.editorProperty().getValue().textProperty().addListener((v, o, n) -> {
if (myChoices.contains(n.toUpperCase())) {
first.setBackground(new Background(new BackgroundFill(Color.rgb(30,30,30), new CornerRadii(0), new Insets(0))));
} else {
first.setBackground(new Background(new BackgroundFill(Color.RED, new CornerRadii(0), new Insets(0))));
}
});
box.getChildren().addAll(first);
}
How about decouplign the Text editor from the ComboBox and link their values?
HBox combo = new HBox();
TextField editor = new TextField();
ComboBox<String> first = new ComboBox<String>();
first.setItems(myChoices);
first.setButtonCell(new ComboBoxListCell<String>(){
#Override public void updateItem(String s, boolean empty) {
super.updateItem(s, empty);
setText(null);
}
});
editor.textProperty().bindBidirectional(first.valueProperty());
combo.getChildren().addAll(editor, first);
box.getChildren().addAll(combo);
Now you have full conroll over the TextField allowing to override any methods etc.

RichTextBox and Inserting at Caret Positions

Here is the deal: I have a RichTextBox control and it works fine. The problem is that there is a button "Insert Current DateTime" which adds/injects the current datetime into the RichTextBox. The user can enter the datetime anywhere where the caret is pointing. This involves complicated string manipulation and stuff.
Any ideas how to get the current caret position. Whenever I get RichTextBox.CaretPositon it seems it is pointing to the start of the RichTextBox and not where the actual caret is.
UPDATE 1:
The date time button click code:
private void DateTimeStampButton_Click(object sender, RoutedEventArgs e)
{
//TextRange tr = new TextRange(textBox.Selection.Start, textBox.Selection.End);
var tr = new TextRange(textBox.Document.ContentStart, textBox.Document.ContentEnd);
if(tr.Text.Length == 2)
{
if(tr.Text == "\r\n")
{
tr.Text = tr.Text.TrimStart(new[] { '\r', '\n' });
}
}
textBox.CaretPosition.InsertTextInRun(DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + ": ");
DateTimeStampButton.Focusable = false;
}
private void SharpRichTextBox_LostFocus(object sender, RoutedEventArgs e)
{
SetValue(TextProperty, Text);
var binding = BindingOperations.GetBinding(this, TextProperty);
if (binding == null) return;
if (binding.UpdateSourceTrigger == UpdateSourceTrigger.Default || binding.UpdateSourceTrigger == UpdateSourceTrigger.LostFocus)
{
// if (TextProperty != null) BindingOperations.GetBindingExpression(this, TextProperty).UpdateSource();
}
}
public string Text
{
get
{
var newValue = new TextRange(Document.ContentStart, Document.ContentEnd).Text.RemoveNewLineAndReturn();
return newValue;
}
set
{
if (!String.IsNullOrEmpty(value))
{
SetValue(TextProperty, value.RemoveNewLineAndReturn());
Document.Blocks.Clear();
Document.Blocks.Add(new Paragraph(new Run(value)));
OnPropertyChanged("Text");
}
}
}
UPDATE 2:
Turned out the problem was with the DateTime button being Focusable. I turned it to be not focusable and it worked as expected. When focus was lost on the RichTextBox it was resetting the caret position. It happened only once since in the code the btn_DateTime was dynamically being set as Focusable = false. I placed Focusable = false in XAML and everything worked fine from the start.
I'm using this code to successfully do what you are attempting:
private void insertNowButton_Click(object sender, RoutedEventArgs e)
{
//NOTE: The caret position does not change.
richTextBox1.CaretPosition.InsertTextInRun(DateTime.Now.ToString());
}
EDIT: Addressing Update 1
private void DateTimeStampButton_Click(object sender, RoutedEventArgs e)
{
var tr = new TextRange(textBox.Document.ContentStart, textBox.Document.ContentEnd);
if (tr.Text.Length == 2)
{
if (tr.Text == "\r\n")
{
tr.Text = tr.Text.TrimStart(new[] { '\r', '\n' });
}
}
/* Changing the text is the only way I can get the date to insert at the beginning */
tr.Text = "I need a beer at ";
textBox.CaretPosition.InsertTextInRun(DateTime.Now.ToString());
}
It looks like SetValue is changing the text so based on my test that actually changing the text resets the caret, I would agree with you that SetValue is causing the problem...
I tried this solution with WPFToolkit.Extended RichTextBox and it didn't work for me.
However I found another one and thought it would be good to post it in here in case someone else could use it.
My problem was also that the after I clicked a button that is supposed to append text at the caret location, it instead adds it at the beginning of the RichTextBox.
So The solution I found is similar to the one in here -
RichTextBox CaretPosition physical location
Instead of using CaretPosition I used RichTextBox.Selection.Start.InsertTextInRun("SomeText").
It considered the selection's start as the caret position even though no selection was made and therefore was good enough for me.
I hope someone will find this useful :)
This worked for me:
private void InsertText(String text, RichTextBox rtb)
{
rtb.CaretPosition = rtb.CaretPosition.GetPositionAtOffset(0, LogicalDirection.Forward);
rtb.CaretPosition.InsertTextInRun(text);
}
I found the code here:
How do I move the caret a certain number of positions in a WPF RichTextBox?

Resources