C#状态模式和事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#状态模式和事件相关的知识,希望对你有一定的参考价值。
在C#中,只有拥有类的事件才能通过受保护的虚拟方法(例如OnClick,OnExit等)触发事件。我想做的就是为某些复杂的类实现GOF状态模式。到目前为止,一切工作都很好,除了我找不到从状态类中触发拥有类事件的方法。
例如,我的按钮有两种状态(上和下),DownState类将检查用户输入,并在必要时触发按钮的Click事件。
public class Button
{
public Button()
{
State = new ButtonStateNormal(this);
}
public event EventHandler<MouseEventArgs> Click;
public ButtonState State { get; set; }
protected virtual void OnClick(MouseEventArgs e)
{
if (Click != null)
Click(this, e);
}
}
public class ButtonStateNormal : ButtonState
{
Button button;
public ButtonStateNormal(Button button)
{
this.button = button;
}
public override void CheckForInput()
{
//...
//Check for user input and change the state
//...
button.State = new ButtonStateDown(button);
}
}
public class ButtonStateDown : ButtonState
{
Button button;
public ButtonStateDown(Button button)
{
this.button = button;
}
public override void CheckForInput()
{
//...
//Check for user input, fire the event of the button and change the state
//...
button.OnClick(new MouseEventArgs(mouse.X, mouse.Y)); //I want to do this, obviously it won't work this way
button.State = new ButtonStateNormal(button);
}
}
我该怎么做?
答案
在ButtonState
类上设置事件或委托,以便您的按钮可以调用。使用后备存储将您在State
中的自动Button
属性更改为一个属性,该属性可在状态改变时钩住和解钩此事件或委托。
public class Button
{
public Button()
{
State = new ButtonStateNormal(this);
}
private ButtonState _state;
public event EventHandler<MouseEventArgs> Click;
public ButtonState State
{
protected get
{
return _state;
}
set
{
if (_state == value)
return;
if (_state != null)
_state.Click -= OnClick;
if (value != null)
value.Click += OnClick;
_state = value;
}
}
protected virtual void OnClick(MouseEventArgs e)
{
if (Click != null)
Click(this, e);
}
public void CheckForInput(){
State.CheckForInput();
}
}
public abstract class ButtonState
{
public abstract void CheckForInput();
public ClickDelegate Click;
public delegate void ClickDelegate(MouseEventArgs a);
}
然后您可以在具体的State类中执行此操作
public class ButtonStateDown : ButtonState
{
Button button;
public ButtonStateDown(Button button)
{
this.button = button;
}
public void CheckForInput()
{
//...
//Check for user input, fire the event of the button and change the state
//...
if(Click != null)
Click(new MouseEventArgs(mouse.X, mouse.Y))
button.State = new ButtonStateNormal(button);
}
}
以上是关于C#状态模式和事件的主要内容,如果未能解决你的问题,请参考以下文章
csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us