1
votes

This is my xaml structure

<StackPanel>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="A"
     LostFocus="text_LostFocus"/>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="B"
     LostFocus="text_LostFocus"/>
</StackPanel>

=> This structure can loop more. Such as:

<StackPanel>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="A"
     LostFocus="text_LostFocus"/>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="B"
     LostFocus="text_LostFocus"/>
</StackPanel>
<StackPanel>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="A"
     LostFocus="text_LostFocus"/>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="B"
     LostFocus="text_LostFocus"/>
</StackPanel>

In .cs file, I define event lost focus as below

private void text_LostFocus(object sender, RoutedEventArgs e)
{
   TextBox textbox = ((TextBox)sender);
   if (textbox.Text.Trim().Length == 0)
   {
      System.Windows.Forms.DialogResult result1 = System.Windows.Forms.MessageBox.Show("Empty string!", "Warning",
                 System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Exclamation);
                textbox.Dispatcher.BeginInvoke((Action)(() => { textbox.Focus(); }));
       return;
    }
    textbox.ScrollToHome();
}

The problem: If there are >= 2 textbox having value is empty ("").

  1. I click first empty textbox => I don't enter any characters.
  2. Then I click second empty textbox.

==> Program always show the message box => If I click OK button, It show another. It occur forever. I can't close the program.

Question: If I have >= 2 empty textbox and I do same as problem above. How can I change the function text_LostFocus to solve the problem???

DEFAULT:

  • Value of these textbox is always empty (DEFAULT)

  • Must use BeginInvoke => Because I want when user click to texbox, user must enter least a character.

1
Funny implementation XD When you have two textboxes, think of what's happening: 1. You enter the first tb 2. You don't enter anything and you click the second one 3. The lostfocus event of tb1 fires and it opens a dialog, and focuses on tb1 again 4. because tb1 got focus, tb2's lostfocus event fires and it does the same, returning focus to tb2 and going on in an infinite loop. - Moti Azu
Also - no need for BeginInvoke. You are already on the UI thread. - Moti Azu
I thought this is WPF an not WinForms, this System.Windows.Forms.DialogResult can be easily replaced with System.Windows.MessageBox! - XAMlMAX
I would advise against showing a pop-up whenever someone leaves a textbox without entering data: it is really annoying. Mark it visually (e.g. a red cross besides it); also don't enable the submit-button until the minimum requirements are met. - BCdotWEB
@GSP BeginInvoke doesn't do what you say, it just runs code on a specific dispatcher. textbox.Dispatcher.BeginInvoke((Action)(() => { textbox.Focus(); })); should be replaced with textbox.Focus(); - Moti Azu

1 Answers

6
votes

I wouldn't use a MessageBox if I were you. WPF has a very good "binding validation framework" (take a look here for a very good tutorial). Otherwise I would create a "warning" label located close each textbox:

<StackPanel>
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="A"
     LostFocus="text_LostFocus"/>
  <TextBlock Name="AWarning" Foreground="Red" />
  <m:TextBoxWithEllipsis IsEllipsisEnabled="True"
     Name="B"
     LostFocus="text_LostFocus"/>
  <TextBlock Name="BWarning" Foreground="Red" />
</StackPanel>

Then in the code-behind:

private void text_LostFocus(object sender, RoutedEventArgs e)
{
    TextBox textBox = ((TextBox)sender);
    TextBlock textBlock = FindName(String.Concat(textBox.Name, "Warning")) as TextBlock;
    textBlock.Text = String.IsNullOrWhiteSpace(textBox.Text) ? "Empty string!" : String.Empty;
}