Мне нужно создать диалог/приглашение, включая TextBox для ввода пользователем. Моя проблема в том, как получить текст после подтверждения диалога? Обычно я бы сделал класс для этого, который сохранил бы текст в свойстве. Однако я хочу, чтобы дизайн Dialog использовал XAML. Поэтому мне нужно каким-то образом расширить XAML-код, чтобы сохранить содержимое TextBox в свойстве, но я думаю, что это невозможно с чистым XAML. Какой был бы лучший способ понять, что я хотел бы сделать? Как создать диалог, который можно определить из XAML, но все же может каким-то образом вернуть вход? Спасибо за любой намек!WPF: создать диалог/приглашение
ответ
«Ответственный» ответ был бы для меня предлагать создать ViewModel для диалога и использовать двустороннюю привязку данных в TextBox, чтобы ViewModel имел свойство «ResponseText», а что нет. Это достаточно легко сделать, но, вероятно, пережить.
Прагматический ответ был бы просто дать ваш текстовое поле в х: Имя так, что он становится членом и выставить текст в качестве свойства в коде позади класса, как так:
<!-- Incredibly simplified XAML -->
<Window x:Class="MyDialog">
<StackPanel>
<TextBlock Text="Enter some text" />
<TextBox x:Name="ResponseTextBox" />
<Button Content="OK" Click="OKButton_Click" />
</StackPanel>
</Window>
Тогда в вашем код позади ...
partial class MyDialog : Window {
public MyDialog() {
InitializeComponent();
}
public string ResponseText {
get { return ResponseTextBox.Text; }
set { ResponseTextBox.Text = value; }
}
private void OKButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
DialogResult = true;
}
}
Затем, чтобы использовать его ...
var dialog = new MyDialog();
if (dialog.ShowDialog() == true) {
MessageBox.Show("You said: " + dialog.ResponseText);
}
Великий ответ Джоша, все кредит ему, я слегка изменил его к этому, однако:
MyDialog Xaml
<StackPanel Margin="5,5,5,5">
<TextBlock Name="TitleTextBox" Margin="0,0,0,10" />
<TextBox Name="InputTextBox" Padding="3,3,3,3" />
<Grid Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Name="BtnOk" Content="OK" Grid.Column="0" Margin="0,0,5,0" Padding="8" Click="BtnOk_Click" />
<Button Name="BtnCancel" Content="Cancel" Grid.Column="1" Margin="5,0,0,0" Padding="8" Click="BtnCancel_Click" />
</Grid>
</StackPanel>
MyDialog код За
public MyDialog()
{
InitializeComponent();
}
public MyDialog(string title,string input)
{
InitializeComponent();
TitleText = title;
InputText = input;
}
public string TitleText
{
get { return TitleTextBox.Text; }
set { TitleTextBox.Text = value; }
}
public string InputText
{
get { return InputTextBox.Text; }
set { InputTextBox.Text = value; }
}
public bool Canceled { get; set; }
private void BtnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
{
Canceled = true;
Close();
}
private void BtnOk_Click(object sender, System.Windows.RoutedEventArgs e)
{
Canceled = false;
Close();
}
И называют это где-то еще
var dialog = new MyDialog("test", "hello");
dialog.Show();
dialog.Closing += (sender,e) =>
{
var d = sender as MyDialog;
if(!d.Canceled)
MessageBox.Show(d.InputText);
}
Вы должны заменить (в определении вашей сетки xaml) 50 * и 50 * на * и *, потому что нет необходимости в 50. – Mafii
Я просто добавить статический метод, называемый MessageBox:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
x:Class="utils.PromptDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
SizeToContent="WidthAndHeight"
MinWidth="300"
MinHeight="100"
WindowStyle="SingleBorderWindow"
ResizeMode="CanMinimize">
<StackPanel Margin="5">
<TextBlock Name="txtQuestion" Margin="5"/>
<TextBox Name="txtResponse" Margin="5"/>
<PasswordBox Name="txtPasswordResponse" />
<StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right">
<Button Content="_Ok" IsDefault="True" Margin="5" Name="btnOk" Click="btnOk_Click" />
<Button Content="_Cancel" IsCancel="True" Margin="5" Name="btnCancel" Click="btnCancel_Click" />
</StackPanel>
</StackPanel>
</Window>
И код позади:
public partial class PromptDialog : Window
{
public enum InputType
{
Text,
Password
}
private InputType _inputType = InputType.Text;
public PromptDialog(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(PromptDialog_Loaded);
txtQuestion.Text = question;
Title = title;
txtResponse.Text = defaultValue;
_inputType = inputType;
if (_inputType == InputType.Password)
txtResponse.Visibility = Visibility.Collapsed;
else
txtPasswordResponse.Visibility = Visibility.Collapsed;
}
void PromptDialog_Loaded(object sender, RoutedEventArgs e)
{
if (_inputType == InputType.Password)
txtPasswordResponse.Focus();
else
txtResponse.Focus();
}
public static string Prompt(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
{
PromptDialog inst = new PromptDialog(question, title, defaultValue, inputType);
inst.ShowDialog();
if (inst.DialogResult == true)
return inst.ResponseText;
return null;
}
public string ResponseText
{
get
{
if (_inputType == InputType.Password)
return txtPasswordResponse.Password;
else
return txtResponse.Text;
}
}
private void btnOk_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
Close();
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
Close();
}
}
Таким образом, вы можете назвать это нравится:
string repeatPassword = PromptDialog.Prompt("Repeat password", "Password confirm", inputType: PromptDialog.InputType.Password);
+1 Для реализации статического метода стиля MessageBox. Краткий, многоразовый код! –
Как только я увидел слово «статический», я проигнорировал другие ответы. Спасибо! :) – maplemale
Вам не нужно ЛЮБОЙ этих других необычных ответов. Ниже приведен упрощенный пример, который не имеет всех свойств Margin
, Height
, Width
, установленных в XAML, но должен быть достаточно, чтобы показать, как это сделать на базовом уровне.
XAML
Построить Window
страницу, как вы обычно и добавить свои поля к нему, скажем, контроль Label
и TextBox
внутри StackPanel
:
<StackPanel Orientation="Horizontal">
<Label Name="lblUser" Content="User Name:" />
<TextBox Name="txtUser" />
</StackPanel>
Затем создайте стандартную Button
для представления (» OK "или" Отправить ") и кнопку« Отмена », если хотите:
<StackPanel Orientation="Horizontal">
<Button Name="btnSubmit" Click="btnSubmit_Click" Content="Submit" />
<Button Name="btnCancel" Click="btnCancel_Click" Content="Cancel" />
</StackPanel>
Code-Behind
Вы добавите функции обработчика Click
событий в коде-позади, но когда вы идете туда, первое, объявить открытую переменную, где вы будете хранить значение текстового поля:
public static string strUserName = String.Empty;
Затем, для функций обработчика событий (щелкните правой кнопкой мыши функцию Click
на кнопке XAML, выберите «Перейти к определению», она создаст ее для вас), вам нужна проверка, чтобы увидеть, пусто ли ваше поле. Вы храните его в переменной, если это не так, и закрыть окно:
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
if (!String.IsNullOrEmpty(txtUser.Text))
{
strUserName = txtUser.Text;
this.Close();
}
else
MessageBox.Show("Must provide a user name in the textbox.");
}
вызова из другой страницы
Вы думаете, если я закрою окно с этим this.Close()
там, мое значение ушел, правда? NO !! Я нашел это с другого сайта: http://www.dreamincode.net/forums/topic/359208-wpf-how-to-make-simple-popup-window-for-input/
Они имели подобный пример этого (я очистил его немного) о том, как открыть ваш Window
от другого и получить значение:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
{
MyPopupWindow popup = new MyPopupWindow(); // this is the class of your other page
//ShowDialog means you can't focus the parent window, only the popup
popup.ShowDialog(); //execution will block here in this method until the popup closes
string result = popup.strUserName;
UserNameTextBlock.Text = result; // should show what was input on the other page
}
}
Отмена кнопки
Вы думаете, ну а как насчет кнопки «Отмена»? Таким образом, мы просто добавим еще одну открытую переменную обратно в нашей всплывающем окне кода позади:
public static bool cancelled = false;
И давайте включим наш btnCancel_Click
обработчик события, и сделать одно изменение в btnSubmit_Click
:
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
cancelled = true;
strUserName = String.Empty;
this.Close();
}
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
if (!String.IsNullOrEmpty(txtUser.Text))
{
strUserName = txtUser.Text;
cancelled = false; // <-- I add this in here, just in case
this.Close();
}
else
MessageBox.Show("Must provide a user name in the textbox.");
}
И тогда мы просто прочитать эту переменную в нашем MainWindow
btnOpenPopup_Click
событие:
private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
{
MyPopupWindow popup = new MyPopupWindow(); // this is the class of your other page
//ShowDialog means you can't focus the parent window, only the popup
popup.ShowDialog(); //execution will block here in this method until the popup closes
// **Here we find out if we cancelled or not**
if (popup.cancelled == true)
return;
else
{
string result = popup.strUserName;
UserNameTextBlock.Text = result; // should show what was input on the other page
}
}
Длинный ответ, но я хотел показать, как легко это использует переменные public static
. Нет DialogResult
, никаких возвращаемых значений, ничего. Просто откройте окно, сохраните свои значения с помощью событий кнопки во всплывающем окне, а затем получите их в функции главного окна.
Существует много способов улучшить предоставленный код: 1) не используйте статические данные для хранения данных, иначе вы иногда сталкиваетесь с проблемами с несколькими диалогами; 2) есть DialogResult для «передачи» истины через ShowDialog(); 3) Атрибут IsCancel для кнопки делает ее истинной кнопкой Отмена без дополнительного кода ... – AntonK
@AntonK 1) Использование статических объектов - это то, как вы можете вызывать переменные в других классах, не создавая их все время. Для меня статические переменные вырезают все это и намного предпочтительнее. Никогда не было проблем с ними, потому что они будут сбрасываться в любое время, когда объект (Окно, Страница), в котором они есть, открывается. Если вам нужно несколько диалогов, создайте диалоговое окно для каждого из них - не используйте один и тот же один много раз или да, это проблематично, но также и плохое кодирование, потому что для чего вы хотите иметь тот же диалог 50 раз? – vapcguy
@AntonK 2) Вы не можете передать «DialogResult» в WPF, это «MessageBoxResult», который я нашел только из стандартных кнопок в диалоговом окне «MessageBox.Show()», а не из пользовательского диалогового окна, .ShowDialog() '- и может запрашивать только стандартные операторы: MessageBoxResult.OK', MessageBoxResult.Cancel',« Да »,« Нет »и т. Д. - не логические или пользовательские значения. 3) 'IsCancel' потребовал бы хранить его в булевом языке и отправить его обратно, так или иначе, так что это было решение одного размера для всех. – vapcguy
- 1. Создать событие в WPF
- 2. Как создать WPF ControlTemplate
- 3. Как создать WPF AutoCompleteBox?
- 4. WPF - создать сетку цветов
- 5. WPF: Создать CheckBox программно
- 6. WPF создать список
- 7. Создать ChildWindow в WPF
- 8. Создать UserControl динамически (WPF)
- 9. WPF Создать шаблон Xaml
- 10. wpf datagrid: создать DatagridNumericColumn в wpf
- 11. Создать программный шаблон в WPF
- 12. WPF Создать видео с AForge
- 13. Создать граничат метку в WPF
- 14. WPF: создать UserControl или CustomControl?
- 15. Как создать WPF Expander Header?
- 16. Создать пользовательский контроль в wpf
- 17. Как создать Listbox динамически wpf
- 18. Как создать редактор формы WPF?
- 19. WPF: создать слайдер медленного движения
- 20. Создать редактируемый элемент дерева wpf
- 21. Создать пустое грани/квадрат wpf
- 22. wpf Как создать пользовательскую кнопку
- 23. WPF создать свой собственный тип
- 24. Создать общий DataGridTemplateColumn в WPF
- 25. Как создать панель выпадающего WPF
- 26. Как создать кроссворд в WPF?
- 27. Создать сообщения журнала в wpf
- 28. Как создать векторные изображения WPF
- 29. Создать панель меню в WPF?
- 30. WPF Создать глобальный сеанс WinSCP
Большое спасибо Джошу и извините за мой поздний ответ! Вначале я слишком много внимания уделял загрузке XAML из файла, а не просто созданию класса, показанного вами. –
+1 для указания прагматичного подхода :) – Jedidja
Вам нужно обработать событие щелчка кнопки OK и установить this.DialogResult = true; для закрытия диалога и диалога dialog.ShowDialog() == true. –