Question

In XAML and WinRT, Is there a way to set up a textbox so that it is disabled for text input until it is tapped.

I tried setting up the Tapped event and then setting the IsEnabled=true, but that only seems to work if the IsEnabled=true in the first place.

I found this on MSDN: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/708c0949-8b06-40ec-85fd-201139ca8b2d

Talks about adding the TappedEvent manually to the event handled for each TextBox, which is cumbersome, but also doesn't seem to work unless IsEnabled was already set to true.

Basically, I want a form where all textboxes display data but are disabled unless the user taps to enable the box and then type.

Was it helpful?

Solution

You can use IsReadOnly instead of IsEnabled to achieve what you are looking for. In addition, you can set up the tapped event handlers in code easily. I'm not sure if setting up handlers in code is a requirement for this to work, as you noted above; however, it does simplify things.

Here are the details.

In the constructor of your page class (here it is MainPage), call the setup function:

public MainPage()
{
    this.InitializeComponent();
    // call the setup for the textboxes
    SetupTextBoxes();
}

Here is where we do the magic - make all textboxes on this page readonly and set up tap handler:

private void SetupTextBoxes()
{
    var tbs = GetVisualChildren<TextBox>(this, true);
    foreach (var tb in tbs)
    {
        tb.IsReadOnly = true;
        tb.AddHandler(TappedEvent, new TappedEventHandler(tb_Tapped), true);
    }
}

Utility function to get a list of all children of the given type (T) of the passed in parent.

private List<T> GetVisualChildren<T>(DependencyObject parent, bool recurse = true)
where T : DependencyObject
{
    var children = new List<T>();
    int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
    for (int i = 0; i < numVisuals; i++)
    {
        DependencyObject v = (DependencyObject)VisualTreeHelper.GetChild(parent, i);
        var child = v as T;
        if (child == null && recurse)
        {
            var myChildren = GetVisualChildren<T>(v, recurse);
            children.AddRange(myChildren);
        }
        if (child != null)
            children.Add(child);
    }
    return children;
}

Finally, the event handler. This enables each textbox when tapped.

private void tb_Tapped(object sender, TappedRoutedEventArgs e)
{
    ((TextBox)(sender)).IsReadOnly = false;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top