How can I force the TextBox to display what is being entered into it?

274 Views Asked by At

In my UWP app, I am invoking a ContentDialog when a button (btnCre8NewMap) is clicked. Here is the pertinent XAML:

<Button x:Name="btnCre8NewMap" Content="Create New Map" ToolTipService.ToolTip="Create a new map" Margin="140,16,50,0" VerticalAlignment="Top" Click="btnCre8NewMap_Click"/>
. . .
<ContentDialog x:Name="cntDlgCre8Map"
Title="Create a New Map"
PrimaryButtonText="Save"
CloseButtonText="Cancel"
DefaultButton="Primary">
    <StackPanel>
    <TextBlock Text="Map Name: "/>
    <TextBox x:Name="txtbxMapName"
        Width="300" HorizontalAlignment="Left"/>
    <TextBlock Text="Default Zoom Level: "/>
    <ComboBox x:Name="cmbxCre8MapZoomLevels"
        Width="100" HorizontalAlignment="Left"/>
    <TextBlock Text="Map Notes: "/>
    <TextBox x:Name="txtbxMapNotes"
        Width="300" Height="300" HorizontalAlignment="Left"/>
    </StackPanel>
</ContentDialog>

...and here is the button click event in the code-behind:

private async void btnCre8NewMap_Click(object sender, RoutedEventArgs e)
{
    try
    {
        string mapName = string.Empty;
        string mapNotes = string.Empty;
        int defaultZoomLevel = 1;
        ClearLocations();
        // Popul8 the cmbx
        for (int i = 1; i < 20; i++)
        {
            cmbxCre8MapZoomLevels.Items.Add(i.ToString());
        }
        ContentDialogResult result = await cntDlgCre8Map.ShowAsync();

        if (result == ContentDialogResult.Primary)
        {    
            mapName = txtbxMapName.Text;
            mapNotes = txtbxMapNotes.Text;
            defaultZoomLevel = cmbxCre8MapZoomLevels.SelectedIndex + 1;
            InsertMapRecord(mapName, mapNotes, preferredZoomLevel);
        }
        // else do nothing (don't save)
    }
    catch (Exception ex)
    {
        MessageDialog exceptionMsgDlg = new MessageDialog(ex.Message, "btnCre8NewMap_Click");
        await exceptionMsgDlg.ShowAsync();
    }
}

This is what I see when I click the button, enter "bla" in txtbxMapName, and enter a bunch of text into txtbxMapNotes:

enter image description here

The problem is that, although txtbxMapName allows me to enter a value ("bla" in the screenshot), txtbxMapNotes shows nothing as I am entering text into it (and notice the "x" in the middle of it). Once I exit the txtbxMapNotes control, what I entered does finally display, though...?!?

What do I need to do to make txtbxMapNotes display what is being entered as it is being entered (not just after leaving the control)?

1

There are 1 best solutions below

4
On

You could use data-binding here to show the text in the blow TextBox when you typed in the top TextBox.

Change ContentDialog Xaml like this:

  <StackPanel>
            <TextBlock Text="Map Name: "/>
            <TextBox x:Name="txtbxMapName" Width="300" HorizontalAlignment="Left" Text="{Binding InputString,Mode= TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
            <TextBlock Text="Default Zoom Level: "/>
            <ComboBox x:Name="cmbxCre8MapZoomLevels" Width="100" HorizontalAlignment="Left"/>
            <TextBlock Text="Map Notes: "/>
            <TextBox x:Name="txtbxMapNotes" Width="300" Height="300" HorizontalAlignment="Left" Text="{Binding InputString, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>

In the code behind, create a new class called ViewModel:

 public class ViewModel: INotifyPropertyChanged 
{
    private string _inputString;

    public string InputString
    {
        get { return _inputString; }
        set
        {
            _inputString = value;
            RaisePropertyChanged("InputString");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

In the code-behind:

 public ViewModel viewModel { get; set; }
    public MainPage()
    {
        this.InitializeComponent();

        viewModel = new ViewModel();

        this.DataContext = viewModel;
    }

I use MainPage to test. You could add the code to the real page in your app.

You might be confused about the INotifyPropertyChanged interface and the Binding markup extension. Please refer to these documents to get more information about data-binding: Data binding overview and Data binding in depth.

Update:

Add TextWrapping="Wrap" to the TextBox to make the clear all button invisible. Like this:

<TextBox x:Name="txtbxMapNotes" Width="300" Height="300" TextWrapping="Wrap" HorizontalAlignment="Left" Text="{Binding InputString, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />