WPF C# InputBox

83,375

Solution 1

I prefer to take an approach using dialogs that doesn't lock up the application, and moves away from the more traditional Win32 Dialog.

Example

Input Dialog

Input Dialog Hidden

Input Dialog not showing.

In this example I use a simplified version of the MVVM based solution I am using for my applications. It may not be pretty, but should give you a solid idea on the basics behind it.

The XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <Button Content="Cool Button" x:Name="CoolButton" Click="CoolButton_Click"/>
        <ListBox x:Name="MyListBox"/>
    </StackPanel>
    
    <!-- It's important that this is in the end of the XAML as it needs to be on top of everything else! -->
    <Grid x:Name="InputBox" Visibility="Collapsed">
        <Grid Background="Black" Opacity="0.5"/>
            <Border
                MinWidth="250"
                Background="Orange" 
                BorderBrush="Black" 
                BorderThickness="1" 
                CornerRadius="0,55,0,55" 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center">
                <StackPanel>
                    <TextBlock Margin="5" Text="Input Box:" FontWeight="Bold" FontFamily="Cambria" />
                    <TextBox MinWidth="150" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="InputTextBox"/>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                        <Button x:Name="YesButton" Margin="5" Content="Yes" Background="{x:Null}" Click="YesButton_Click"/>
                        <Button x:Name="NoButton" Margin="5" Content="No" Background="{x:Null}" Click="NoButton_Click" />
                    </StackPanel>
                </StackPanel>
            </Border>
        </Grid>
    </Grid>
</Window>

It's very easy to show this dialog as you only need to set the Visibility of the InputBox grid to visible. You then simply handle the Yes / No buttons and get the Input text from the TextBox.

So instead of using code that requires ShowDialog(), you simply set the Visibility option to Visible. There are still some things to do in this example that we will handle in code-behind, like for example clearing the InputText box after handling the Yes/No Button clicks.

The code-behind:

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void CoolButton_Click(object sender, RoutedEventArgs e)
        {
            // CoolButton Clicked! Let's show our InputBox.
            InputBox.Visibility = System.Windows.Visibility.Visible;
        }

        private void YesButton_Click(object sender, RoutedEventArgs e)
        {
            // YesButton Clicked! Let's hide our InputBox and handle the input text.
            InputBox.Visibility = System.Windows.Visibility.Collapsed;

            // Do something with the Input
            String input = InputTextBox.Text;
            MyListBox.Items.Add(input); // Add Input to our ListBox.

            // Clear InputBox.
            InputTextBox.Text = String.Empty;
        }

        private void NoButton_Click(object sender, RoutedEventArgs e)
        {
            // NoButton Clicked! Let's hide our InputBox.
            InputBox.Visibility = System.Windows.Visibility.Collapsed;

            // Clear InputBox.
            InputTextBox.Text = String.Empty;
        }
    }
}

The code-behind could easily be done using a Dependency, or as ViewModel logic in this case, but for simplicity I kept it in the code-behind.

Solution 2

Here is my solution. It is fully customizable.

string inputRead = new InputBox("text").ShowDialog();

Or, if you prefer

string inputRead= new InputBox("Insert something", "Title", "Arial", 20).ShowDialog()

And this is the code of the class

public class InputBox
{

    Window Box = new Window();//window for the inputbox
    FontFamily font = new FontFamily("Tahoma");//font for the whole inputbox
    int FontSize=30;//fontsize for the input
    StackPanel sp1=new StackPanel();// items container
    string title = "InputBox";//title as heading
    string boxcontent;//title
    string defaulttext = "Write here your name...";//default textbox content
    string errormessage = "Invalid answer";//error messagebox content
    string errortitle="Error";//error messagebox heading title
    string okbuttontext = "OK";//Ok button content
    Brush BoxBackgroundColor = Brushes.GreenYellow;// Window Background
    Brush InputBackgroundColor = Brushes.Ivory;// Textbox Background
    bool clicked = false;
    TextBox input = new TextBox();
    Button ok = new Button();
    bool inputreset = false;

    public InputBox(string content)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        windowdef();
    }

    public InputBox(string content,string Htitle, string DefaultText)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        try
        {
            title = Htitle;
        }
        catch 
        {
            title = "Error!";
        }
        try
        {
            defaulttext = DefaultText;
        }
        catch
        {
            DefaultText = "Error!";
        }
        windowdef();
    }

    public InputBox(string content, string Htitle,string Font,int Fontsize)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        try
        {
            font = new FontFamily(Font);
        }
        catch { font = new FontFamily("Tahoma"); }
        try
        {
            title = Htitle;
        }
        catch
        {
            title = "Error!";
        }
        if (Fontsize >= 1)
            FontSize = Fontsize;
        windowdef();
    }

    private void windowdef()// window building - check only for window size
    {
        Box.Height = 500;// Box Height
        Box.Width = 300;// Box Width
        Box.Background = BoxBackgroundColor;
        Box.Title = title;
        Box.Content = sp1;
        Box.Closing += Box_Closing;
        TextBlock content=new TextBlock();
        content.TextWrapping = TextWrapping.Wrap;
        content.Background = null;
        content.HorizontalAlignment = HorizontalAlignment.Center;
        content.Text = boxcontent;
        content.FontFamily = font;
        content.FontSize = FontSize;
        sp1.Children.Add(content);

        input.Background = InputBackgroundColor;
        input.FontFamily = font;
        input.FontSize = FontSize;
        input.HorizontalAlignment = HorizontalAlignment.Center;
        input.Text = defaulttext;
        input.MinWidth = 200;
        input.MouseEnter += input_MouseDown;
        sp1.Children.Add(input);
        ok.Width=70;
        ok.Height=30;
        ok.Click += ok_Click;
        ok.Content = okbuttontext;
        ok.HorizontalAlignment = HorizontalAlignment.Center;
        sp1.Children.Add(ok);

    }

    void Box_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if(!clicked)
        e.Cancel = true;
    }

    private void input_MouseDown(object sender, MouseEventArgs e)
    {
        if ((sender as TextBox).Text == defaulttext && inputreset==false)
        {
            (sender as TextBox).Text = null;
            inputreset = true;
        }
    }

    void ok_Click(object sender, RoutedEventArgs e)
    {
        clicked = true;
        if (input.Text == defaulttext||input.Text == "")
            MessageBox.Show(errormessage,errortitle);
        else
        {
            Box.Close();
        }
        clicked = false;
    }

    public string ShowDialog()
    {
        Box.ShowDialog();
        return input.Text;
    }
}

Hope it can be useful.

Solution 3

Just create another Window class in your Visual Studio-project, which holds the username in a public property. Then create an instance of this window somewhere in your main window, and Show it using the ShowDialog method. This blocks until your "dialog" window is closed. Then you can get the username from the public property and do whatever you want with it.

Solution 4

Create/Add a new Window in your project for taking input from the user. You can then use Window.Show or Window.ShowDialog to show that window as a pop up Window

Also add an OK button n created window and on OK button click save the information in the text file

Solution 5

Thank you!! My modificated version:

public class InputBox
{
    Window Box = new Window();//window for the inputbox
    FontFamily font = new FontFamily("Avenir");//font for the whole inputbox
    int FontSize = 14;//fontsize for the input
    StackPanel sp1 = new StackPanel();// items container
    string title = "Dica s.l.";//title as heading
    string boxcontent;//title
    string defaulttext = "";//default textbox content
    string errormessage = "Datos no válidos";//error messagebox content
    string errortitle = "Error";//error messagebox heading title
    string okbuttontext = "OK";//Ok button content
    string CancelButtonText = "Cancelar";
    Brush BoxBackgroundColor = Brushes.WhiteSmoke;// Window Background
    Brush InputBackgroundColor = Brushes.Ivory;// Textbox Background
    bool clickedOk = false;
    TextBox input = new TextBox();
    Button ok = new Button();
    Button cancel = new Button();
    bool inputreset = false;


    public InputBox(string content)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        windowdef();
    }

    public InputBox(string content, string Htitle, string DefaultText)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        try
        {
            title = Htitle;
        }
        catch
        {
            title = "Error!";
        }
        try
        {
            defaulttext = DefaultText;
        }
        catch
        {
            DefaultText = "Error!";
        }
        windowdef();
    }

    public InputBox(string content, string Htitle, string Font, int Fontsize)
    {
        try
        {
            boxcontent = content;
        }
        catch { boxcontent = "Error!"; }
        try
        {
            font = new FontFamily(Font);
        }
        catch { font = new FontFamily("Tahoma"); }
        try
        {
            title = Htitle;
        }
        catch
        {
            title = "Error!";
        }
        if (Fontsize >= 1)
            FontSize = Fontsize;
        windowdef();
    }

    private void windowdef()// window building - check only for window size
    {
        Box.Height = 100;// Box Height
        Box.Width = 450;// Box Width
        Box.Background = BoxBackgroundColor;
        Box.Title = title;
        Box.Content = sp1;
        Box.Closing += Box_Closing;
        Box.WindowStyle = WindowStyle.None;
        Box.WindowStartupLocation = WindowStartupLocation.CenterScreen;

        TextBlock content = new TextBlock();
        content.TextWrapping = TextWrapping.Wrap;
        content.Background = null;
        content.HorizontalAlignment = HorizontalAlignment.Center;
        content.Text = boxcontent;
        content.FontFamily = font;
        content.FontSize = FontSize;
        sp1.Children.Add(content);

        input.Background = InputBackgroundColor;
        input.FontFamily = font;
        input.FontSize = FontSize;
        input.HorizontalAlignment = HorizontalAlignment.Center;
        input.Text = defaulttext;
        input.MinWidth = 200;
        input.MouseEnter += input_MouseDown;
        input.KeyDown += input_KeyDown;

        sp1.Children.Add(input);

        ok.Width = 70;
        ok.Height = 30;
        ok.Click += ok_Click;
        ok.Content = okbuttontext;

        cancel.Width = 70;
        cancel.Height = 30;
        cancel.Click += cancel_Click;
        cancel.Content = CancelButtonText;

        WrapPanel gboxContent = new WrapPanel();
        gboxContent.HorizontalAlignment = HorizontalAlignment.Center;

        sp1.Children.Add(gboxContent);
        gboxContent.Children.Add(ok);
        gboxContent.Children.Add(cancel);

        input.Focus();
    }

    void Box_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
       //validation
    }

    private void input_MouseDown(object sender, MouseEventArgs e)
    {
        if ((sender as TextBox).Text == defaulttext && inputreset == false)
        {
            (sender as TextBox).Text = null;
            inputreset = true;
        }
    }

    private void input_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter && clickedOk == false )
        {
            e.Handled = true;
            ok_Click(input, null);
        }

        if (e.Key == Key.Escape)
        {
            cancel_Click(input, null);
        }
    }

    void ok_Click(object sender, RoutedEventArgs e)
    {
        clickedOk = true;
        if (input.Text == defaulttext || input.Text == "")
            MessageBox.Show(errormessage, errortitle,MessageBoxButton.OK,MessageBoxImage.Error);
        else
        {
            Box.Close();
        }
        clickedOk = false;
    }

    void cancel_Click(object sender, RoutedEventArgs e)
    {
        Box.Close();
    }

    public string ShowDialog()
    {
        Box.ShowDialog();
        return input.Text;
    }
}
Share:
83,375
user981924
Author by

user981924

Updated on December 18, 2021

Comments

  • user981924
    user981924 over 2 years

    I am building a WPF application using C#. I want to pop out a dialog box to prompt the user to enter his/her name. After that, I will keep track of the name and save some data into a .txt file using the name.

    For example:

    Name input is
    name = "John"

    And so I have data
    data="1, 2, 3";

    and then I save the "data" in John.txt file.

    Does anyone know how to do it?

    I think the problem is how to pop out a dialog for the user to enter name.

  • user981924
    user981924 over 12 years
    Yup I got the idea. Thank You!
  • Marc
    Marc almost 11 years
    How to you prevent the 'InputBox' control from losing focus while it is shown?
  • eandersson
    eandersson almost 11 years
    @Marc I have created a custom control based on the ContentControl element for my dialog, and inside that I override OnVisibleChanged, and if the dialog is visible I set Keyboard.Focus(textBox);.
  • Marc
    Marc almost 11 years
    @eandersson OK but how do you prevent losing focus? When the control is visible and the user presses tab multiple times, the focus will be given to controls behind this user control. I'd like to prevent that. It should remain within the user control.
  • Marc
    Marc almost 11 years
    @eandersson I solved the problem by disabling (IsEnabled=false) all the underlying controls.
  • eandersson
    eandersson almost 11 years
    That works. I actually misunderstood the issue. I basically have this controller in the very top of my control, so nothing else can take focus.