Sequence of keyboard focus events and tag setting

Hi all.

I have been investigating processing of TextBox contents based on detection of keyboard focus events.

I had assumed that if an entry is typed and then the TAB key hit … detection of keyboard focus leaving the TextBox would guarantee that the associated tag value had already been set.

My investigation suggests that this is not the case … which seems very odd to me.

If an entry is typed and the ENTER key hit, followed by the TAB key … the tag value is seen, as this is ensured through earlier use of the ENTER key.

Surely it would be sensible if use of the TAB key to leave the field had the same effect. Anway … assuming there is a good reason for ignoring the data entry, does anyone know of a work-around method to implement that behaviour?

I am aware of the ability to introduce KeyDown and PreviewKeyDown handlers. Could they be used to ensure the entry is written to the TextBox tag?

Regards,
Greg Shearer

Hello Greg,

We understand you are having and issue while trying to save a Tag value by changing TextBoxes pressing TAB.
On our tests the Tag value is saved automatically when the TAB key is pressed.

To assist you further, could you kindly provide us with additional details about the configuration of the textboxes in your project? Additionally, it would be helpful for us to know which version of FactoryStudio you are currently using.

Best Regards,
Tatsoft Team.

Hi.

Just to be clear … the Tag value is saved when the TAB key is hit … however it appears to be saved AFTER IsKeyboardFocusWithinChanged indicates that focus has left the TextBox.

I had expected the Tag value to be saved BEFORE IsKeyboardFocusWithinChanged indicates focus change, so that the value could processed according to the application requirements. That is, I would like to test/process the Tag value ON EXIT from the TextBox. Is there a standard method available for this need? If so, I have not found it.

Is my interpretation above correct? I believe that it is, but it does also seem odd to me that IsKeyboardFocusWithinChanged should indicate before the Tag value is set.

My license details are:
image

Hello Greg,

By default, the Tag Value is saved on the “LostFocus” event. However, if your project requires using the “IsKeyboardFocusWithinChanged” event, you can follow this simple workaround: Assign the Event handler and retrieve the name of the Tag assigned to the TextBox:

Assign the Event handler and retrieve the name of the Tag assigned to the TextBox:

TTextBox textBox1;
textBox1 = this.CurrentDisplay.GetControl("textBox1") as TTextBox;
textBox1.IsKeyboardFocusWithinChanged += this.TextBox_IsKeyboardFocusWithinChanged;
textBox1.Tag = @Tag.Text1.GetName();

In the Event handler, make sure to declare the sender as TTextBox and use TK.SetObjectValue to update your Tag value:

private void TextBox_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
	TTextBox textBox = sender as TTextBox;
	if(textBox == null)
		return;
		
	string tag = TConvert.ToString(textBox.Tag);
	string text = textBox.Text;
	TK.SetObjectValue(tag, text); 
}

Following this method, the updated tag value can be utilized within the event handler.

Please let us know if you have any other questions.

Best Regards,
Tatsoft Team.

Thanks for your response, as I expect that method will help with my problem.

However I should ask … can the LostFocus event be used in a similar way but more directly?
I think I had investigated that earlier, but hadn’t had any succes.
If you can similarly indicate how LostFocus could be used, I will try that as well.

I apologise for asking what may seem very basic questions, but from my perspective these methods seem to assume some underlying expert knowledge … which I clearly don’t have.

I do appreciate your assistance :slight_smile:

Regards,
Greg Shearer

Hello Greg,

We´re glad the method provided seems helpful for your problem.

The LostFocus event can be used similarly the IsKeyboardFocusWithinChanged, like below:

textBox1.LostFocus += this.TextBox_LostFocus;

In the Event handler:

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    // Your code here.
}

A more directly way to create this is shown below:

textBox1.LostFocus += (sender, e) =>
{
    // Your code here.
};

Please let us know if you have any other questions.

Best Regards,
Tatsoft Team.

Hi again.

I have been trying out use of the LostFocus event, and thought all was going well … but have found another confusing issue.

When I use the Handler routine below with the MsgBox included, all works well:

confirmation = CurrentDisplay.GetControl(TTB_confirmation)
confirmation.Tag = @Tag.sample.confirmation.GetName()
AddHandler confirmation.LostFocus, AddressOf ConfirmationFocusLost

Sub ConfirmationFocusLost()

MsgBox(@Tag.sample.confirmation)
@Script.Class.sample_identification.confirmation_changed()

@Tag.processing_grid= 0
End Sub

I do realise that placing a MsgBox() within a handler is not recommended … but it seems to indicate that the tag has been set. I now suspect that is an illusion.

image

That is, @Tag.sample.confirmation appears to be available within the Handler, and when the MsgBox is closed the following procedure behaves as expected.

However … when the MsgBox is instead placed within the executed procedure … the tag appears to not have been set.

image

So … I remain confused … as it appears that the tag value has not actually been set by the time the LostFocus event is raised.

Hello Greg,

We made some tests and when the MsgBox is placed within the executed procedure, the tag had been set too.

Can you send us a example tproj file that implements exactly what you are saying? So we can run some tests to determine what is causing your problem.

Bests Regards,
Tatsoft Team.

I will put together a small application when I have the chance … but that may be a while off … and it probably won’t display the same behaviour knowing my luck.

However, within my current application there definitely seems to be a system timing related problem.

If I place MsgBox within the called procedure it consistently displays the tag as being empty, even though TraceWindow and Property Watch indicate that the tag is set.

More particularly, if I place MsgBox before the tag is first referenced, by the time I click the ok button the tag is seen as set, so the procedure executes as if the tag is set.

image

However, if I place MsgBox after the tag is first referenced, the tag has already been acted on as if it is not set.

image

Any ideas?

PS
The time interval reported in TraceWindow between the tag (Tag.sample.confirmation) being set and it not being seen within the called procedure is 2 ms, as shown below.

Also … this behaviour is the same even when the procedure is run from the GotFocus event of the field being tabbed into! This is the configuration in place for the above image. The behaviour is as if there are two slightly different views of the tag within the application … which I’m sure can’t be the case.

Hello Greg,

It appears that you have some problems with the MsgBox within the executed procedure, is it really necessary to use the MsgBox or executed a procedure to check the tag value?

If not, to ensure that the tag value is indeed properly set, you can incorporate the following script into the LostFocus event. This script will enable you to trace and verify the tag value:

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
	TTextBox textBox = sender as TTextBox;
	if(textBox == null)
		return;
		
	string tag = TConvert.ToString(textBox.Tag);
	string tagValue = TConvert.ToString(TK.GetObjectValue(tag));
	
	@Info.Trace("TextBox_LostFocus || Tag: " + tag + " || TagValue: " + tagValue + " || Text: " + textBox.Text);
}

If it doesn’t helps you, we await the example tproj file to make some tests.

Please let us know if you have any other questions.

Bests Regards,
Tatsoft Team.