简体   繁体   English

使用MVP从Presenter更新View组件的更好方法

[英]Better approach for updating View components from Presenter, using MVP

I recently started working with WinForms via MVP (PassiveView) pattern and stuck on 我最近开始通过MVP(PassiveView)模式使用WinForms ,并坚持使用
"How to make View update itself while presenter does long (for like 20 seconds) async operations" “如何在主持人进行长时间(约20秒)异步操作时使View自身更新”

So I have a form, an IView implementation with UI items: 所以我有一个表单,一个带有UI项的IView实现:

  • a Button on which my presenter is subscribed to via Click event; 通过Click事件订阅我的演示者的Button
  • a DataGridView with a checkbox column; 具有复选框列的DataGridView
  • A ProgressBar ; 一个ProgressBar ;
  • and two fields. 和两个领域。 Current and SelectedCount ; CurrentSelectedCount ;

So what am I doing there? 那我在那里做什么?
On that Click , my Presenter grabs "checked" items from datagrid and writes them to database. 在该Click ,我的Presenter从datagrid抓取“选中”的项目并将其写入数据库。
Since that processing takes time, I made this method async : 由于该处理需要时间,因此我使此方法async

private async void PutToDatabase(List<Item> items)
{
    View.SelectedCount = items.Count;
    for (int i = 0; i < items.Count; i++)
    {
        await Task.Factory.StartNew(
         () =>
            {
                // writing stuff to database via ADO.NET
                View.Current = i;
            });
    }
}

So I am updating my Current, which updates my progressBar by doing this: 因此,我正在更新Current,通过执行以下操作更新了progressBar:

public int CurrentPrice
{
    get { return _current; }
    set
    {
        _current = value;
        Invoke((MethodInvoker) delegate {progBarImportState.Value = _current; });
    }
}

I'm not sure, if this approach is going to work fine, since I can't reload my UI to use the form again, unless I gonna check somwhere (eg in the same delegate) if progress.value == progress.maximum and rollback the form to reuse it. 我不确定这种方法是否能正常工作,因为我无法重新加载UI来再次使用该表单,除非我要检查某处(例如在同一委托中) if progress.value == progress.maximum并回滚表单以重新使用它。 Plus, it doesn't look 'pretty'. 另外,它看上去并不“漂亮”。

So are there any more effective/cleaner solution than this? 那么,有没有比这更有效/更清洁的解决方案了?

Why don't you use Back ground workers, pretty old school but woks good. 您为什么不使用Back Ground工人,漂亮的老学校但炒锅还不错。 Click here for more info on Background Workers. 单击此处以了解有关背景工作者的更多信息。 You can use the Background-Worker like this: 您可以像这样使用Background-Worker:

private void Main(string[] args)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += Bw_DoWork;
    bw.RunWorkerCompleted += Bw_RunWorkerCompleted;

    //Parameter you need to work in Background-Thread for example your strings
    string[] param = new[] {"Text1", "Text2", "Text3", "Text4"};

    //Start work
    bw.RunWorkerAsync(param);
}

//Do your Background-Work
private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
    string[] param = e.Argument as string[];

    //Process your long running  task

    e.Result = null; //Set your Result of the long running task
}

//Taking your results
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //Apply your Results to your GUI-Elements
    myTextBox1.Text = e.Result.ToString();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM