Как я могу заставить текстовое поле отображать то, что в него вводится?

#textbox #winrt-xaml #uwp-xaml #contentdialog

#текстовое поле #winrt-xaml #uwp-xaml #contentdialog

Вопрос:

В моем приложении UWP я вызываю ContentDialog при нажатии кнопки (btnCre8NewMap). Вот соответствующий 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>
 

… и вот событие нажатия кнопки в коде:

 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();
    }
}
 

Это то, что я вижу, когда нажимаю кнопку, ввожу «bla» в txtbxMapName и ввожу кучу текста в txtbxMapNotes:

введите описание изображения здесь

Проблема в том, что, хотя txtbxMapName позволяет мне вводить значение («bla» на скриншоте), txtbxMapNotes ничего не показывает, когда я ввожу в него текст (и замечаю «x» в середине). Как только я выхожу из элемента управления txtbxMapNotes, то, что я ввел, наконец отображается, хотя …?!?

Что мне нужно сделать, чтобы txtbxMapNotes отображал то, что вводится при вводе (а не сразу после выхода из элемента управления)?

Ответ №1:

Вы могли бы использовать data-binding here для отображения текста в текстовом поле blow при вводе в верхнем текстовом поле.

Измените ContentDialog Xaml следующим образом:

   <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>
 

В коде создайте новый класс с именем 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));
        }
    }
}
 

В коде:

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

        viewModel = new ViewModel();

        this.DataContext = viewModel;
    }
 

Я использую MainPage для тестирования. Вы можете добавить код на реальную страницу в своем приложении.

Возможно, вас смущают INotifyPropertyChanged interface и Binding markup extension . Пожалуйста, обратитесь к этим документам, чтобы получить больше информации о привязке данных: обзор привязки данных и подробное описание привязки данных.

Обновить:

Добавьте TextWrapping=»Wrap» в текстовое поле, чтобы сделать кнопку очистить все невидимой. Вот так:

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

Комментарии:

1. Спасибо, Рой; но почему одно текстовое поле работает нормально, а другое нет? Единственное очевидное отличие заключается в том, что второе имеет определенную высоту…

2. @B.ClayShannon Не могли бы вы сказать мне, чем вы управляете, пока другой не работает нормально? Когда вы вводите текст в верхнем текстовом поле, тот же текст будет отображаться в нижнем текстовом поле. Вы имеете в виду, что кнопка очистки закрывает текст?

3. Да, как упоминалось в моем вопросе, ничего не отображается при вводе в нижний / больший (более высокий) Текстовое поле, когда я в него набираю, и в его середине отображается «x». Что такое «кнопка очистки»?

4. Извините за опечатку, это «кнопка очистки». Он используется для удаления всего текста в текстовом поле. Очень простой способ сделать его невидимым заключается в том, что вы можете установить TextWrapping="Wrap" в своем xaml. Я также обновил свой ответ, и вы можете его проверить.