编程语言
首页 > 编程语言> > c# – 事件循环

c# – 事件循环

作者:互联网

在以下情况下我经常发现自己:

我有一个绑定到某些数据的用户控件.每当更新控件时,都会更新基础数据.每当更新基础数据时,控件都会更新.因此,很容易陷入永无止境的更新循环(控制更新数据,数据更新控制,控制更新数据等).

通常我通过使用bool(例如updatedByUser)解决这个问题,因此我知道控件是以编程方式还是由用户更新,然后我可以决定是否触发事件以更新基础数据.这似乎不是很整洁.

是否有一些处理此类方案的最佳实践?

编辑:我添加了以下代码示例,但我想我已回答了我自己的问题……?

public partial class View : UserControl
{
    private Model model = new Model();

    public View()
    {
        InitializeComponent();
    }

    public event EventHandler<Model> DataUpdated;

    public Model Model
    {
        get
        {
            return model;
        }
        set
        {
            if (value != null)
            {
                model = value;
                UpdateTextBoxes();
            }
        }
    }

    private void UpdateTextBoxes()
    {
        if (InvokeRequired)
        {
            Invoke(new Action(() => UpdateTextBoxes()));
        }
        else
        {
            textBox1.Text = model.Text1;
            textBox2.Text = model.Text2;
        }
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
        model.Text1 = ((TextBox)sender).Text;
        OnModelUpdated();
    }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {
        model.Text2 = ((TextBox)sender).Text;
        OnModelUpdated();
    }

    private void OnModelUpdated()
    {
        DataUpdated?.Invoke(this, model);
    }
}

public class Model
{
    public string Text1 { get; set; }
    public string Text2 { get; set; }
}

public class Presenter
{
    private Model model;
    private View view;

    public Presenter(Model model, View view)
    {
        this.model = model;
        this.view = view;

        view.DataUpdated += View_DataUpdated;
    }

    public Model Model
    {
        get
        {
            return model;
        }
        set
        {
            model = value;
            view.Model = model;
        }
    }

    private void View_DataUpdated(object sender, Model e)
    {
        //This is fine.
        model = e;

        //This causes the circular dependency.
        Model = e;
    }
}

解决方法:

你正在寻找的是Data Binding.它允许你连接两个或多个属性,这样当一个属性改变时,其他属性将自动神奇地更新.

在WinForms中它有点难看,但在你的情况下就像魅力一样.首先,您需要一个表示数据的类,并实现INotifyPropertyChanged以在数据更改时通知控件.

public class ViewModel : INotifyPropertyChanged
{

    private string _textFieldValue;
    public string TextFieldValue {
        get
        {
            return _textFieldValue;
        }

        set
        {
            _textFieldValue = value;
            NotifyChanged();
        }
    }

    public void NotifyChanged()
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(null));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

在Form / Control中,将ViewModel.TextFieldValue的值绑定到textBox.Text.这意味着只要TextFieldValue的值发生更改,Text属性就会更新,每当Text属性发生更改时,TextFieldValue都会更新.换句话说,这两个属性的值将是相同的.这解决了你遇到的循环循环问题.

public partial class Form1 : Form
{
    public ViewModel ViewModel = new ViewModel();

    public Form1()
    {
        InitializeComponent();
        // Connect:  textBox1.Text <-> viewModel.TextFieldValue
        textBox1.DataBindings.Add("Text", ViewModel , "TextFieldValue");
    }
}

如果需要修改Form / Control外部的值,只需设置ViewModel的值即可

form.ViewModel.TextFieldValue = "new value";

控件将自动更新.

标签:c,user-interface,winforms,circular-reference
来源: https://codeday.me/bug/20190628/1310576.html