如果我们在对话框给用户输入值时,当用户输入空值点击确定按钮时,应该给个提示然后让用户继续输入。
如果在方法里使用 return false;,结果用户输入空值时对话框还是会关闭。正确做法如下:
先设置自定义对话框的属性:
autoClose: false
然后当用户输入正确的值时
$.closeModal();
关闭对话框。
调用顺序很重要
如果你想显示一个模态对话框,你需要先将所有者窗口禁用,然后启用模态对话框,当关闭一个模态对话框时,则要确保严格按照相反的流程来进行。
为什么要按照这样的流程呢?
如果你没有按照正确的顺序启用或禁用窗口,则窗口的输入焦点可能会被搞乱。
如果关闭了一个模态对话框,你可能想要这样做:
> 关闭并销毁模态对话框
> 重新启用所有者窗口但是,如果你按照上面的顺序操作的话,你会发现:所有者窗口将不会像正常的那样在前景激活。它会随机地激活一些其他的窗口。可以显式的调用激活函数来解决这个问题,但是,这种做法会带来窗口的闪烁,并且窗口的Z序也乱了。
到底发生了什么?
当你销毁一个模态对话框时,你是在销毁一个前景激活的窗口。Windows窗口管理器需要找到下一个被激活的窗口。它首先会尝试激活模态对话框的所有者窗口,但是此时所有者窗口被禁用了。
这个时候,Windows窗口管理器会跳过所有者窗口并寻找系统中其他未被激活的窗口。这就是导致出现上述现象的原因。那么,应该怎么做?
正确的销毁模态对话框的流程如下:
> 启用模态对话框所有者窗口
> 销毁模态对话框这次,当我们的模态对话框被销毁时,Windows窗口管理器发现所有者窗口是已启用状态,所以它就会将输入焦点设置到所有者窗口并将它激活为前景窗口。
总结
按照上面提到的顺序,可以避免诸如界面闪烁,输入焦点混乱的问题。虽然是一个小知识点,但是也值得一试。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The correct order for disabling and enabling windows》
如果我们在对话框给用户输入值时,当用户输入空值点击确定按钮时,应该给个提示然后让用户继续输入。
如果在方法里使用 return false;,结果用户输入空值时对话框还是会关闭。正确做法如下:
先设置自定义对话框的属性:
autoClose: false
然后当用户输入正确的值时
$.closeModal();
关闭对话框。
转载于:https://www.cnblogs.com/GGDong/p/10995520.html
在
WPF应用程序中,我想实现以下似乎不能直接起作用的行为:
从主窗口(Window1),用户打开非模态窗口(Window2),并且该非模态窗口可以显示模态对话框(Window3).
问题是,只要显示模态对话框,当用户关闭对话框时,主窗口就会在后台消失(假设有其他应用程序的窗口打开).
我使用Window.Owner和Window.Show()/ Window.ShowDialog()的方式有什么不对,它是一个bug还是它不支持的东西?
以下简单的WPF应用程序演示了此行为:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender,RoutedEventArgs e)
{
Window2 win = new Window2();
win.Owner = this;
win.Show();
}
}
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
}
private void Button_Click(object sender,RoutedEventArgs e)
{
Window3 win = new Window3();
win.Owner = this;
win.ShowDialog();
}
private void btnClose_Click(object sender,RoutedEventArgs e)
{
this.Close();
}
}
public partial class Window3 : Window
{
public Window3()
{
InitializeComponent();
}
private void btnClose_Click(object sender,RoutedEventArgs e)
{
this.Close();
}
}
XAML Window1:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1">
Show non-modal window
XAML Window2:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2">
Show modal dialog
Close
XAML Window3:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window3">
Close
更新:修复了代码中的复制和粘贴错误.这是.NET 3.5 SP1,如果它很重要.
Android自定义对话框提供用户输入选项
最近在写一个关于服务器站点性能量化评分的小功能,主要是根据Apdex公式来进行评判的,需要提供一个让用户自己设置最优响应时间门槛的值的选项。由于页面空间的限制,采取了通过弹出自定义对话框的形式来实现这一功能,具体实现如下:
Apdex详解http://blog.csdn.net/sunny_sailor/article/details/51240313
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/compare_edit_last_set"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:text="@string/compare_edit_default"/>
</LinearLayout>
<LinearLayout
android:layout_marginLeft="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/compare_edit_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="5"
android:hint="@string/compare_edit_set"
android:imeOptions="actionDone"
android:maxHeight="48dp"
android:minLines="1"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_alignBaseline="@id/compare_edit_time"
android:layout_marginRight="16dp"
android:layout_weight="1"
android:maxHeight="48dp"
android:text="@string/compare_edit_set_unit">
</TextView>
</LinearLayout>
</LinearLayout>
/**
* 提供设置量化评分的T值对话框
*/
private void settingDialog(final Context context)
{
final SharedPreferences.Editor editor = mPreferences.edit();
LayoutInflater layoutInflater = LayoutInflater.from(context);
//获取自定义的视图
View editView = layoutInflater.inflate(R.layout.dialog_compare_edit,null);
//省略部分代码
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getString(R.string.compare_edit_title));
//设置视图
builder.setView(editView);
//获取输入的值
final EditText eTime = (EditText)editView.findViewById(R.id.compare_edit_time);
builder.setPositiveButton(getString(R.string.button_ok), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if(("").equals(eTime.getText().toString()))
{
Toast.makeText(context,getString(R.string.input_reminder),Toast.LENGTH_SHORT)
.show();
changeShowing(false,dialog);
}
else{
int time = Integer.valueOf(eTime.getText().toString());
if(time <1 || time > 100000)
{
Toast.makeText(context,getString(R.string.input_reminder),Toast.LENGTH_SHORT)
.show();
changeShowing(false,dialog);
}else{
//还原PositiveButton的关闭效果
changeShowing(true,dialog);
}
}
}
}).setNegativeButton(getString(R.string.button_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//还原NegativeButton的关闭效果
changeShowing(true,dialog);
}
}).create().show();
}
/**
* mShowing是Dialog类的一个成员变量,在setPositiveButton中改变之后会影响setNegativeButton,
* 如点击“取消”按钮将不能关闭对话框,解决办法在“取消”的onClick事件中再改变mShowing的值
* @param isShow
* @param dialog
*/
private void changeShowing(boolean isShow,DialogInterface dialog){
//通过反射机制得到变量并改变变量的值
try {
Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");
field.setAccessible(true);
field.set(dialog, isShow);
} catch (Exception e) {
e.printStackTrace();
}
}
上面代码中的changeShowing方法仅仅适用于android.app.AlertDialog,如果使用的是v7包下的AlertDialog,则可以使用如下代码代替来达到输入数据不正确或为空时,点击按钮对话框不关闭的效果。
/**
* 提供设置量化评分的T值对话框
*/
private void settingDialog(final Context context)
{
LayoutInflater layoutInflater = LayoutInflater.from(context);
View editView = layoutInflater.inflate(R.layout.dialog_compare_edit,null);
TextView lastSetTimeText = (TextView)editView.findViewById(R.id.compare_edit_last_set);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getString(R.string.compare_edit_title));
builder.setView(editView);
//获取输入的值
final EditText eTime = (EditText)editView.findViewById(R.id.compare_edit_time);
builder.setPositiveButton(getString(R.string.button_ok),null);//只设置文本,而不添加监听事件
builder.setNegativeButton(getString(R.string.button_cancel),null);//只设置文本,而不添加监听事件
final AlertDialog alertDialog = builder.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(("").equals(eTime.getText().toString()))
{
Toast.makeText(context,getString(R.string.input_reminder),Toast.LENGTH_SHORT)
.show();
}
else{
//do something
//关闭对话框
alertDialog.dismiss();
}
}
}
});
}