我有一个WPF的程序,按钮的单击响应函数的执行需要2秒以上的时间。在测试的时候发现,如果连续单击了两次按钮,那么这个函数就会执行两次,而不像Win32里面的那样,函数没有执行完之前是不会再次发出单击消息的。这个特性正是我不需要的。
如果我想在按钮响应函数执行完毕之前的所有单击事件都取消掉,就像Win32里面一样,函数执行完毕之前,不再发出单击消息的话,该如何处理?我曾尝试过,在函数执行之前,Disable按钮,退出之前Enable按钮,依然解决不了问题。
如果我想在按钮响应函数执行完毕之前的所有单击事件都取消掉,就像Win32里面一样,函数执行完毕之前,不再发出单击消息的话,该如何处理?我曾尝试过,在函数执行之前,Disable按钮,退出之前Enable按钮,依然解决不了问题。
解决方案 »
- C#中查询SQl如何将SqlDataReader转换成string付给文本框呢?
- sql2005升级到sql2008
- .net部署安装问题
- 问个菜鸟级的问题,如果将含有特殊符号的字符串添加的access中!(在线等)
- c#中GridView问题
- 如何判连要一个静态网页是否存在
- C#如何实现抓取网络资源
- 64位电脑中的32位winfrom程序怎么弄通过一个窗口句柄访问一个64位窗口的文件路径
- 推荐给希望了解应用程序开发全过程的“初学者”一本书!!!!!!!!!
- 找合作伙伴:C#程序员一位
- 刚装的VS2008无法运行程序 :找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
- 图形闪烁,怎么解决???
bool processing;
void 响应函数(object sender, RoutedEventArgs e)
{
if(processing == true) return;
try
{
processing = true;
//执行需要2秒以上
}
finally
{
processing = false;
}
}
也许是我有个地方没有说清楚。
我只是想让响应函数执行完毕之前得所有点击都无效,也就是那些重复的点击。一旦函数执行完毕之后,后续的点击还是要执行这个函数的。只是屏蔽函数执行过程中的点击事件。
{
System.Threading.Thread.Sleep(2000);
MessageBox.Show("M");
}
另外按钮灰化是有效的,要设置IsEnabled属性为false。
int i = 0;
private void button_Click(...)
{
i++;
button.Content = i.ToString();
Thread.Sleep(2000);
}
然后双击一下,i的值就变成2了。我用的是VS2010
的确是点几次就是几。
我是基于最干净的WPF项目,最原始的微软WPF按钮来测试的,请确保测试条件一致。
你能不能把你的项目文件发给我看一下,我对比一下哪里有问题?
WinForm的使用的还是Win32的消息循环,我知道是没问题的。但是我的WPF就有问题,唉。
下面给出解决方案: public class WpfApplication
{
private static DispatcherOperationCallback exitFrameCallback = new DispatcherOperationCallback(ExitFrame); public static void DoEvents()
{
DispatcherFrame nestedFrame = new DispatcherFrame();
DispatcherOperation exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, exitFrameCallback, nestedFrame); Dispatcher.PushFrame(nestedFrame);
if (exitOperation.Status != DispatcherOperationStatus.Completed)
{
exitOperation.Abort();
}
} private static Object ExitFrame(Object state)
{
DispatcherFrame frame = state as DispatcherFrame;
frame.Continue = false;
return null;
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
button.IsEnabled = false;
WpfApplication.DoEvents();
i++;
button.Content = i.ToString();
System.Threading.Thread.Sleep(2000);
button.IsEnabled = true;
}添加WpfApplication.DoEvents();来让按钮灰化得以立刻执行,否则你禁用按钮是要在整个事件结束后才会响应,那样就没有意义了。
wpf时我没发现类似的方法。但感觉耗时操作,肯定要用多线程:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
label1.Content = i.ToString();
} int i = 0;
private void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false; Thread thread = new Thread(new ThreadStart(delegate()
{
Thread.Sleep(2000);
this.Dispatcher.Invoke(new Action(() =>
{
button1.IsEnabled = true;
}));
})); thread.Start(); label1.Content = (++i).ToString();
}
}
bool processing;
void 响应函数(object sender, RoutedEventArgs e)
{
if(processing == true) return;
try
{
processing = true;
//执行需要2秒以上
}
finally
{
processing = false;
}
}
不考虑多线程的话这是一个很简单的锁,不是同时触发的话应该不会多次进入。
唯一的可能就是你事件添加了多次。
int i = 0;
private void button1_Click(...)
{
i++;
button1.Content = i.ToString();
Thread.Sleep(2000);
}
问题依旧。按理说,.net的目的就是在任何机器上运行都一致,这下麻烦了。
顺便问一下,你的处理器是几个核心的?装过VS2010 SP1没有?
我的是双核的,装了VS2010 SP1
按钮名.Click-=响应事件;