How to trigger validation with a button click - c#

Upon instantiating my program, I have a textbox that already has a red border around it indicating that validation has already been triggered. I would only like the validation triggered once the user has inputted something in the textbox. This works in my other textboxes, I'm just wondering if this only happens because the binding mode is OneWayToSource, and if so, how would I be able to change this behavior to my other textboxes?

I presume you are using WPF? If so your object needs to implement IDataErrorInfo. You can then tell the textbox when it should show the error. eg:
string System.ComponentModel.IDataErrorInfo.this[string columnName]
{
get
{
switch (columnName.ToLower())
{
case "code":
if (string.IsNullOrWhiteSpace(this.Code)) return "Required field";
break;
case "name":
if (string.IsNullOrWhiteSpace(this.Name)) return "Required field";
break;
}
return null;
}
}

Related

C# Window From Autoselects Text

I have not dealt with WinForms for a long time.
Now I'm stuck with something trivial but cannot figure it out.
I have a Winform and when a Timer Tick happens I want to show a message in a new form message box:
frmMessage frmM = new frmMessage();
frmM.txtMessage.Text = ConfigurationSettings.AppSettings["Message"];
frmM.Show();
It works but the text in the textbox shows as selected(with a blue background).
I tried
txtMessage.SelectionLength = 0;
Did not help.
Also tried to set focus to a different control, did not help either.
for now, as a workaround, I will use a Label.
This is a consequence of the way TextBox Class is implemented. If a selection is not specifically set, all text will be selected when the control gets focus.
From TextBox.OnGotFocus:
Protected override void OnGotFocus(EventArgs e) {
base.OnGotFocus(e);
If (!selectionSet) {
// We get one shot at selecting when we first get focus. If we don't
// do it, we still want to act Like the selection was set.
selectionSet = true;
// If the user didn't provide a selection, force one in.
If (SelectionLength == 0 && Control.MouseButtons == MouseButtons.None) {
SelectAll();
}
}
Additionally due to the way the SelectionLength Property is implemented, setting that property to zero does not set the selectionSet` flag as it is already zero.
Instead, set the TextBox.SelectionStart Property immediately after setting the text as this will set that flag.
txtMessage.SelectionStart = 0;
However, your work-a-round of using a Label to display a message is much more appropriate than using an input control.
This is not the best answer but it works. You can try this
frmMessage frmM = new frmMessage();
frmM.txtMessage.Text = "";
frmM.txtMessage.AppendText(ConfigurationSettings.AppSettings["Message"]);
frmM.Show();

Change Textbox text from another frame(container)

I see here lot of similar question, but I still not find answer that help me in situation.
I have two frame(lets say FrameChild), one is "in" another(practically FrameChild is in this frame, lets say FrameMain).
When I insert all parameters in FrameChild and tap on button witch is on bottom of FrameMain I call method that return string...
Now when i get string i need to change textbox text in FrameChild
I have tray many way.
First idea was something like:
FrameChild frm = new FrameChild;
frm.textbox.text = "somestring";
But nothing happen.
Than i thing use some property.
in FrameChield:
public string setTicNo
{
set
{
textBox.Text = value;
}
}
in FrameMain:
FrameChild frm = new FrameChild;
frm.setTicNo = "somestring";
When i debbuging I get value, but textbox still is empty...
On the end I try to bind textbox text on setTicNo;
public string setTicNo
{
get
{
return setTicNo;
}
set
{
setTicNo = value;
}
}
Xaml:
Text = {Binding setTicNo, Mode=TwoWay,UpdateSourceTrigger=Explicit}
(here i try use more bindings, but every time i get infinite loop.
Please help , I not have more ideas..
Thanx
Did you try building a single view model and bind it to both frames, if it was passed by ref which is the default it will change the value once you do.
A side note implement a INOTIFYPROPERTYCGANGED in the View model

Why won't these class properties display in the view, and why can't breakpoints be set on them?

I have a bizarre problem that I can't figure out. I have a domain object similar to the following, with two custom getter properties that (a) do not return any visible value in the view when called, and (b) will not let me set a breakpoint on them to inspect them during execution.
(Note: There are other similar questions regarding setting breakpoints on auto-property setters -- that is NOT my question. My problem is regarding formally declared get{} properties.)
Here's an example of how my domain model looks:
public class Program : IProgram
{
public string Code { get; set; }
public string Title { get; set; }
public string StatusCode { get; set; }
public DateTime StatusDate { get; set; }
public bool HasCompleted
{
get
{
return (StatusCode == "A" || StatusCode == "B");
}
}
public string HumanizedStatus
{
get
{
switch (StatusCode)
{
case "0": return "Text for 0"; break;
case "1": return "Text for 1"; break;
case "2": return "Text for 2"; break;
case "3": return "Text for 3"; break;
case "4": return "Text for 4"; break;
case "5": return "Text for 5"; break;
case "A": return "Text for A"; break;
case "B": return "Text for B"; break;
case "C": return "Text for C"; break;
case "D": return "Text for D"; break;
case "E": return "Text for E"; break;
case "W": return "Text for W"; break;
default : return "UNKNOWN"; break;
}
}
}
}
This model is attached to a ViewModel that is rendered as a set of table rows in the view as follows:
#foreach (var program in Model.Programs)
{
<tr>
<td>#program.Code</td>
<td>#program.Title</td>
<td>#program.StatusDate</td>
<td>#program.HumanizedStatus</td>
<td>#program.HasCompleted</td>
</tr>
}
In the view I see the displayed text for #program.Code, #program.Title, and #program.StatusDate, but I see nothing in the view for #program.HumanizedStatus or #program.HasCompleted. There are other properties displayed after that in my screen and they show up fine as well.
When I attempt to set a breakpoint on either of those properties (by clicking in the left gutter) I get the red ball as expected, but they are never hit when the view is rendered. I can set other breakpoints just fine, and breakpoints set in methods all execute normally, but here they do not. I can also verify via breakpoint in the controller that the model is properly constructed, but the HumanizedStatus property returns null at that point and the HasCompleted method returns false. So I suspect the debugger is showing default "uninitialized" values for them, but I can't figure out why they aren't called. I even added this to the controller action:
if (programs[0].HasCompleted)
{
//nop
}
and set a breakpoint on it to inspect the first Program object in the list, and it also returned false for HasCompleted and null for HumanizedStatus. I also tried this answer for manually setting the breakpoint and received an error message "IntelliSense could not find the specified location. Do you still want to set the breakpoint?". Even if I select "Yes" it still never fires.
I could change them to methods, but then AutoMapper throws an error, which I could work around by excluding them from the mapping, but that is jumping through hoops I shouldn't have to jump through.
The properties are declared in the interface. I am using VS2010, MVC 3.
Many thanks in advance for any help!

Using IDataErrorInfo on related but non-mutually exclusive checkboxes

I have a series of checkboxes on a form. One or more must be checked, and if not I want to display an error icon on them until one of them is.
My IDataErrorInfo implementation looks like so:
public string this[string columnName]
{
get
{
switch (columnName)
{
case "option1":
case "option2":
case "option3":
if (!this.option1 && !this.option2 && !this.option3)
return "Please select one or more of the 3 options";
}
}
}
Now, if none of the checkboxes that are bound to options1-3 are checked, each checkbox will have an error icon on them, which is fine, but when one of them IS checked, only that one checkbox will have its error icon removed (as opposed to all of them).
What's the ideal way of having the form re-poll validation for options1-3 when any one of them is changed?
If it helps (though I don't think it should be much different from normal winforms controls), I'm using DevExpress UI controls, so the checkboxes are CheckBoxEdit's and the ErrorProvider is the DxErrorProvider.
EDIT: SOLVED
I ended up manually notifying of property changed for the other options when one was changed.
private bool option1;
public bool Option1
{
get { return this.option1; }
set
{
this.option1 = value;
this.notifyPropertyChanged("Option1");
this.notifyPropertyChanged("Option2");
this.notifyPropertyChanged("Option3");
}
}
// repeat for options2-3

determine a textbox's previous value in its lost focused event? WPF

I have a textbox and have an onlostfocus event on it.
Inside the lostfocus method, is there a way I can determine if the user has actually changed the value in it?
i.e how do i get hold of any previous value in it?
Thanks
As with just about everything else in WPF, this is easier if you use data binding.
Bind the text box to a class property. By default, bindings update the source when the bound control loses focus, so you don't have to muck around with the LostFocus event. You then have access to both the new value and the value that the user entered in the property setter.
In the XAML it looks like this:
<TextBox Text="{Binding MyProperty, Mode=TwoWay}"/>
In the class it looks like this:
private string _MyProperty;
public string MyProperty
{
get { return _MyProperty; }
set
{
// at this point, value contains what the user just typed, and
// _MyProperty contains the property's previous value.
if (value != _MyProperty)
{
_MyProperty = value;
// assuming you've implemented INotifyPropertyChanged in the usual way...
OnPropertyChanged("MyProperty");
}
}
What comes to mind for me is a two stage approach. Handle the TextChanged event on the textbox and flag it. Then when the textbox OnLostFocus occurs you can simply check your flag to see if the text has been changed.
Here is a code snippet on how you could handle the tracking.
public class MyView
{
private bool _textChanged = false;
private String _oldValue = String.Empty;
TextChanged( ... )
{
// The user modifed the text, set our flag
_textChanged = true;
}
OnLostFocus( ... )
{
// Has the text changed?
if( _textChanged )
{
// Do work with _oldValue and the
// current value of the textbox
// Finished work save the new value as old
_oldValue = myTextBox.Text;
// Reset changed flag
_textChanged = false;
}
}
}
Store the original value somewhere. You could write a common component to store the value when it gets focus and compare the value when it loses focus. I've done this in ASP.NET and it works quite well.
Another way to solve this by databinding:
Bind the TextBox.Text to the property, that holds the inital value, but use a binding with
UpdateSourceTrigger=Explicit
Then, when the textbox loses focus, you can check the binding if source and target values differ, using this code snippet and evaluating the resulting BindingExpression:
BindingExpression be = tb.GetBindingExpression(TextBox.TextProperty);
Some more code can be found here:
http://bea.stollnitz.com/blog/?p=41

Categories