在我的应用程序中,我有一个Button
。如果单击该按钮,则执行针对数据库的选择,结果显示在ListView
中。
由于选择非常复杂,因此检索数据需要一些时间。
单击Button
时,应禁用应用程序 - Window
,直到加载数据。
但是当我将窗口的IsEnabled
- 属性设置为false时,窗口会在加载数据后被禁用。
我尝试在Window
的其他帖子中禁用BackgroundWorker
。但后来我得到一个例外,该窗口已经被另一个线程使用了。
如何禁用它检索数据的Window
bevore?
答案 0 :(得分:2)
你在后台线程中做错了什么。您必须从UI线程影响UI,并且您的数据加载应该在后台线程中进行。
最简单的方法是使用BackgroundWorker加载数据,将数据存储在类级变量中,当后台工作为complete时,UI会重新启用并加载来自类级变量的数据。
答案 1 :(得分:1)
我认为你会将数据库活动转移到后台线程,以使你的UI保持响应(即使它只是禁用它),而不是相反。
答案 2 :(得分:0)
试试这个:
BackgroundWorkerHelper.DoWork<Type of object you want to retrieve>(
() =>
{
//Load your data here
//Like
using (MarketingService svc = new MarketingService())
{
return svc.GetEmployeeLookupTable();
}
},
(args) =>
{
this.IsEnable = true;
if (args.Error == null)
{
Your Target Datasource= args.Result;
}
});
this.IsEnable = false;
答案 3 :(得分:0)
除了背景线程之外,我还建议使用“BusyDialog”窗口。
Yous busy对话框可以是显示正在执行操作的动画,也可以模拟阻止任何用户输入。
public partial class BusyDialog : Window
{
public BusyDialog()
{
InitializeComponent();
}
public static T Execute<T>(DependencyObject parent, Func<T> action)
{
Window parentWindow = null;
if (parent is Window)
{
parentWindow = parent as Window;
}
else
{
parentWindow = Window.GetWindow(parent);
}
T val = default(T);
Exception le = null;
BusyDialog bd = new BusyDialog();
bd.Owner = parentWindow;
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
val = action();
}
catch (Exception ex)
{
le = ex;
}
bd.EndDialog();
});
bd.ShowDialog();
if (le != null)
{
Trace.WriteLine(le.ToString());
throw new Exception("Execute Exception", le);
}
return val;
}
private void EndDialog()
{
Dispatcher.Invoke((Action)delegate() {
this.DialogResult = true;
});
}
}
现在,您可以使用以下方式异步调用方法
List<Result> results = BusyDialog.Execute( this ,
()=>{
return MyLongDatabaseLoadingCall();
});
这就是发生的事情,