以下似乎是一个相对常见的模式(对我来说,而不是整个社区)将字符串变量绑定到TextBox的内容.
class MyBackEndClass
{
public event EventHandler DataChanged;
string _Data;
public string Data
{
get { return _Data; }
set
{
_Data = value;
//Fire the DataChanged event
}
}
}
class SomeForm : // Form stuff
{
MyBackEndClass mbe;
TextBox someTextBox;
SomeForm()
{
someTextBox.TextChanged += HandleTextBox();
mbe.DataChanged += HandleData();
}
void HandleTextBox(Object sender, EventArgs e)
{
mbe.Data = ((TextBox)sender).Text;
}
void HandleData(Object sender, EventArgs e)
{
someTextBox.Text = ((MyBackEndClass) sender).Data;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是更改TextBox会触发后端数据值的更改,从而导致文本框发生更改等.这会永远运行.
有没有更好的设计模式(除了诉诸讨厌的布尔标志)正确处理这种情况?
编辑:要清楚,在实际设计中,后端类用于同步多个表单之间的更改.因此,我不能直接使用SomeTextBox.Text属性.
Billy3
好吧,我已经写了一些代码,但你可能不喜欢它:)
public class DataChangedEventArgs : EventArgs
{
public string Data { get; set; }
public DataChangedEventArgs(string data)
{
Data = data;
}
}
public delegate void DataChangedEventHander(DataChangedEventArgs e);
public class BackEnd
{
public event DataChangedEventHander OnDataChanged;
private string _data;
public string Data
{
get { return _data; }
set
{
_data = value;
RaiseOnDataChanged();
}
}
private static readonly object _sync = new object();
private static BackEnd _instance;
public static BackEnd Current
{
get
{
lock (_sync)
{
if (_instance == null)
_instance = new BackEnd();
return _instance;
}
}
}
private void RaiseOnDataChanged()
{
if(OnDataChanged != null)
OnDataChanged(new DataChangedEventArgs(Data));
}
}
public class ConsumerControl
{
public event EventHandler OnTextChanged;
private string _text;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
if (OnTextChanged != null)
OnTextChanged(this, EventArgs.Empty);
}
}
}
public class Consumer
{
public ConsumerControl Control { get; set; }
public Consumer()
{
Control = new ConsumerControl();
BackEnd.Current.OnDataChanged += NotifyConsumer;
Control.OnTextChanged += OnTextBoxDataChanged;
}
private void OnTextBoxDataChanged(object sender, EventArgs e)
{
NotifyBackEnd();
}
private void NotifyConsumer(DataChangedEventArgs e)
{
Control.Text = e.Data;
}
private void NotifyBackEnd()
{
// unsubscribe
BackEnd.Current.OnDataChanged -= NotifyConsumer;
BackEnd.Current.Data = Control.Text;
// subscribe again
BackEnd.Current.OnDataChanged += NotifyConsumer;
}
}
public class BackEndTest
{
public void Run()
{
var c1 = new Consumer();
var c2 = new Consumer();
c1.Control.Text = "1";
BackEnd.Current.Data = "2";
}
}
Run Code Online (Sandbox Code Playgroud)
主要的 idia 在这里:
// unsubscribe
BackEnd.Current.OnDataChanged -= NotifyConsumer;
BackEnd.Current.Data = Control.Text;
// subscribe again
BackEnd.Current.OnDataChanged += NotifyConsumer;
Run Code Online (Sandbox Code Playgroud)