我需要创建一个对话框/提示,包括用于用户输入的文本框。我的问题是,确认对话框后如何获取文本?通常我会为此创建一个类,将文本保存在属性中。但是我想使用XAML设计对话框。因此,我将不得不扩展XAML代码以将TextBox的内容保存在属性中-但是我想这对于纯XAML是不可能的。实现我想要做的最好的方法是什么?如何构建一个可以从XAML定义但仍然可以某种方式返回输入的对话框?感谢您的提示!
我需要创建一个对话框/提示,包括用于用户输入的文本框。我的问题是,确认对话框后如何获取文本?通常我会为此创建一个类,将文本保存在属性中。但是我想使用XAML设计对话框。因此,我将不得不扩展XAML代码以将TextBox的内容保存在属性中-但是我想这对于纯XAML是不可能的。实现我想要做的最好的方法是什么?如何构建一个可以从XAML定义但仍然可以某种方式返回输入的对话框?感谢您的提示!
Answers:
“负责任”的回答是建议我为对话框建立一个ViewModel,并在TextBox上使用双向数据绑定,以便ViewModel具有“ ResponseText”属性或不具有“ ResponseText”属性。这很容易做到,但可能会适得其反。
务实的答案是给您的文本框一个x:Name,以便它成为成员,并将文本作为属性公开在类后面的代码中,如下所示:
<!-- 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);
}
我只是添加一个静态方法来像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);
MessageBox
-style静态方法。简洁,可重用的代码!
Josh的好答案,都归功于他,不过我对此做了些微修改:
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);
}
WindowStyle="ToolWindow"
在“窗口”上进行设置可以使其看起来更好。也WindowStartupLocation="CenterOwner"
和dialog.Owner = this;
在父窗口的中心位置是
你不需要任何这些花哨的答案。下面是没有所有的一个简单的例子Margin
,Height
,Width
性能在XAML确定,但应该足以展示如何在一个基本水平这件事。
XAML像通常一样
构建一个Window
页面,并向其中添加字段,例如aLabel
和TextBox
a内的控件StackPanel
:
<StackPanel Orientation="Horizontal">
<Label Name="lblUser" Content="User Name:" />
<TextBox Name="txtUser" />
</StackPanel>
然后根据需要创建Button
提交标准(“确定”或“提交”)和“取消”按钮:
<StackPanel Orientation="Horizontal">
<Button Name="btnSubmit" Click="btnSubmit_Click" Content="Submit" />
<Button Name="btnCancel" Click="btnCancel_Click" Content="Cancel" />
</StackPanel>
代码隐藏
您将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()
停在上面,我的价值就消失了,对吗? 没有!!我是从另一个站点发现的: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
,没有返回值,什么也没有。只需打开窗口,将带有按钮事件的值存储在弹出窗口中,然后在主窗口功能中检索它们即可。
DialogResult
在WPF中,这是MessageBoxResult
,我发现从标准按钮只能在一个MessageBox.Show()
对话框-通过未示出一个从自定义对话框.ShowDialog()
-并且只能查询标准的运营商MessageBoxResult.OK
,MessageBoxResult.Cancel
“是” ,“否”等-不是布尔值或自定义值。3)IsCancel
无论如何都需要将其存储在布尔值中并将其发送回去,因此这是一种万能的解决方案。