Winfrom 异步线程设置主界面焦点问题

wlqxm 2017-02-13 09:24:31
界面FrmCashier


方法:
//设置焦点
private void SetActiveControl()
{
if (this.InvokeRequired)
{
this.Invoke(new Action(SetActiveControl));
}
else
{
bool CalcManualCode = chbCalcManualCode.Checked;
if (CalcManualCode) this.ActiveControl = dgvServiceDetail;//设置dataGridView
else this.ActiveControl = txtManualCode;//设置文本框焦点
}
}

//异步线程(单列模式)Loading窗口(ShowDialog)
TaskHelper.GetInstance.StartTask(() =>
{
//设置方法
CheckMemberCard(mcvlist, cardCode);

}, new FrmPrompt(this));


//异步设置具体实现

/// <summary>
/// 单例对象
/// </summary>
public static TaskHelper GetInstance
{
get
{
if (null == instance)
{
Interlocked.CompareExchange(ref instance, new TaskHelper(), null);
}
return instance;
}
}

/// <summary>
/// 启动异步任务
/// </summary>
/// <param name="taskAction">要异步执行的操作委托</param>
/// <param name="promptForm">异步执行中显示的提示窗口(null表示不显示)</param>
/// <returns></returns>
public Task StartTask(Action taskAction, Form promptForm)
{
return Task.Factory.StartNew(() =>
{
ShowPrompt(promptForm);
try
{
taskAction();
}
finally
{
ClosePrompt(promptForm);
}
});
}
/// <summary>
/// 弹出提示窗口
/// </summary>
/// <param name="promptForm">窗口对象</param>
public void ShowPrompt(Form promptForm)
{
if (promptForm == null || promptForm.Owner == null)
return;
Form ownerForm = promptForm.Owner;
if (!IsFormCreated(ownerForm))
return;
ownerForm.BeginInvoke(new Action(() =>
{
if (!promptForm.Visible)
promptForm.ShowDialog();
}));
}





//选中方法
private void CheckMemberCard(List<MemberService.MemberCardView> mcvlist, string whereText)
{
....
CheckMemberCard(mcvid);
}


//设置焦点具体调用
private void CheckMemberCard(Guid mcid, bool isLoadBill = false)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<Guid, bool>(CheckMemberCard), mcid, isLoadBill);
}
else
{
//调用设置焦点方法
SetActiveControl();
}
}



问题:为什么设置焦点后会闪一下,然后回到默认焦点?

...全文
253 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wlqxm 2017-02-15
  • 打赏
  • 举报
回复
@wangjun8868 还是没有解决,写在了最后还是有问题
wlqxm 2017-02-14
  • 打赏
  • 举报
回复
引用 7 楼 wangjun8868 的回复:
[quote=引用 5 楼 wlqxm 的回复:] [quote=引用 4 楼 wangjun8868 的回复:]

 Task.Run(() => {
              //这里写你复杂的耗时的业务逻辑
            }).ContinueWith(t => 
            { 
                //这里设置控件焦点
                this.Invoke(new Action(() => { this.textBox1.Focus(); }));
            }); 
我这里用的4.0,没有Task.Run,你的意思是在异步执行后再委托设置,我的情况是异步里面有条件需要成立后,在方法: private void CheckMemberCard(Guid mcid, bool isLoadBill = false)里面,条件成立才能设置焦点[/quote] 意思就是 你得保证那个方法 执行完毕再获取焦点,既然你用4.0 你可可以用ManualResetEvent 来控制吧 参考 http://blog.csdn.net/jhycjhyc/article/details/7223426[/quote] 好的 谢谢了
  • 打赏
  • 举报
回复
很混乱,很强迫症地去“要去设置焦点”。没工夫细看。 给你一个建议:如果有2个以上东西想当然地去“设置焦点”,则根本不要去想当然地区设置什么焦点。
编程有钱人了 2017-02-14
  • 打赏
  • 举报
回复
引用 5 楼 wlqxm 的回复:
[quote=引用 4 楼 wangjun8868 的回复:]

Task.Run(() => {
//这里写你复杂的耗时的业务逻辑
}).ContinueWith(t =>
{
//这里设置控件焦点
this.Invoke(new Action(() => { this.textBox1.Focus(); }));
});

我这里用的4.0,没有Task.Run,你的意思是在异步执行后再委托设置,我的情况是异步里面有条件需要成立后,在方法:
private void CheckMemberCard(Guid mcid, bool isLoadBill = false)里面,条件成立才能设置焦点[/quote]
意思就是 你得保证那个方法 执行完毕再获取焦点,既然你用4.0 你可可以用ManualResetEvent 来控制吧

参考
http://blog.csdn.net/jhycjhyc/article/details/7223426
SoulRed 2017-02-14
  • 打赏
  • 举报
回复
异步调用UI线程是要委托才能调用的。并不是直接能调用
wlqxm 2017-02-14
  • 打赏
  • 举报
回复
引用 4 楼 wangjun8868 的回复:

 Task.Run(() => {
              //这里写你复杂的耗时的业务逻辑
            }).ContinueWith(t => 
            { 
                //这里设置控件焦点
                this.Invoke(new Action(() => { this.textBox1.Focus(); }));
            }); 
我这里用的4.0,没有Task.Run,你的意思是在异步执行后再委托设置,我的情况是异步里面有条件需要成立后,在方法: private void CheckMemberCard(Guid mcid, bool isLoadBill = false)里面,条件成立才能设置焦点
编程有钱人了 2017-02-14
  • 打赏
  • 举报
回复

 Task.Run(() => {
              //这里写你复杂的耗时的业务逻辑
            }).ContinueWith(t => 
            { 
                //这里设置控件焦点
                this.Invoke(new Action(() => { this.textBox1.Focus(); }));
            }); 
编程有钱人了 2017-02-14
  • 打赏
  • 举报
回复

   Task.Run(() => {
                this.Invoke(new Action(() => { this.textBox1.Focus(); }));  
            }).ContinueWith(t => {  this.Invoke(new Action(() => { this.textBox2.Focus(); })); }); 
最后的焦点在 this.textBox2 上

   Task.Run(() => {
                this.Invoke(new Action(() => { this.textBox2.Focus(); }));  
            }).ContinueWith(t => {  this.Invoke(new Action(() => { this.textBox1.Focus(); })); }); 
最后的焦点在 this.textBox1 上.
wlqxm 2017-02-14
  • 打赏
  • 举报
回复
引用 1 楼 wangjun8868 的回复:
异步乱用导致的,如果要先实现那个效果,请确保那个控件是最后自行的,可以 回调信号来实现,或者保证异步执行的顺序
你好,能详细的说一下吗?什么时候回调好一点,此处回调应该怎么写呢,谢谢
编程有钱人了 2017-02-14
  • 打赏
  • 举报
回复
异步乱用导致的,如果要先实现那个效果,请确保那个控件是最后自行的,可以 回调信号来实现,或者保证异步执行的顺序

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧