C#自定义事件模拟风吹草摇摆

这是一个自定义事件的例子。C#、WinForm、Visual Studio 2017。
在HoverTreeForm中画一块草地,上面有许多草(模拟)。
HewenqiTianyi类模拟天气,会引发“风”事件(HoverTreeWindEvent),风有东风或西风,或静止。
当吹东风,草往西边倒,吹西风则往东边到。静止则草不会东歪西倒。
草地上每一颗草都监听HoverTreeWindEvent事件,根据风向(WindDdirection)调整姿态。
HewenqiTianyi中有定时器,每隔一段时间触发调整风向的事件。
由于监听到的“风”事件不是WinForm中的线程,要改变WinForm中“草”的姿态,
使用了BeginInvoke方法和委托,在WinForm线程外访问控件。具体看HoverTreeGrass用户控件。
by 何问起 
参考:http://hovertree.com/h/bjag/k0qps1iw.htm
http://hovertree.com/h/bjag/cm8k4ja1.htm
效果图:

HewenqiTianyi类代码:

using System;
using System.Timers;

namespace TianYiHeWenQi
{
    class HewenqiTianyi
    {
        public static event ActionEventHandler HoverTreeWindEvent;
        WindEventArgs _arg = new WindEventArgs();
        public HewenqiTianyi()
        {
            Timer h_timer = new Timer();
            h_timer.Interval = 3000;
            h_timer.Elapsed += H_timer_Elapsed;
            h_timer.Start();
        }
        Random _HoverClock=new Random ();
        private void H_timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _arg.WindType = (WindDdirection)(_HoverClock.Next(3));
            OnAction(_arg);
        }

        protected void OnAction(WindEventArgs ev)
        {
            HoverTreeWindEvent?.Invoke(ev);
            //相当于以下代码
            //if (HoverTreeWindEvent != null)
            //{
            //    HoverTreeWindEvent(ev);
            //}
        }
    }

    class WindEventArgs : EventArgs
    {
        public WindDdirection WindType { get; set; }
    }

    enum WindDdirection
    {
        East,
        West,
        Static
    }

    delegate void ActionEventHandler(WindEventArgs ev);

}

自定义用户控件代码:

using System;
using System.Windows.Forms;

namespace TianYiHeWenQi
{
    public partial class HoverTreeGrass : UserControl
    {
        delegate void MySetText(string text);
        public HoverTreeGrass()
        {
            InitializeComponent();
            HewenqiTianyi.HoverTreeWindEvent += HewenqiTianyi_HoverTreeWindEvent;
        }

        private void UpdateLabel(WindDdirection wd)
        {
            if (label_grass.InvokeRequired)
            {
                // 当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它
                Action<WindDdirection> actionDelegate = (x) => {
                    switch (x)
                    {
                        case WindDdirection.East:
                            label_grass.Location = new System.Drawing.Point(40 - 9, label_grass.Location.Y);
                            label_grass.Text="\\";
                            break;
                        case WindDdirection.West:
                            label_grass.Location = new System.Drawing.Point(40+9, label_grass.Location.Y);
                            label_grass.Text = "/";
                            break;
                        case WindDdirection.Static:
                            label_grass.Location = new System.Drawing.Point(40, label_grass.Location.Y);
                            label_grass.Text = "|";
                            break;
                    }
                };
                // 或者
                // Action<string> actionDelegate = delegate(string txt) { this.label_grass.Text = txt; };
                this.label_grass.BeginInvoke(actionDelegate, wd);
            }
            else
            {
                switch (wd)
                {
                    case WindDdirection.East:
                        label_grass.Text = "\\";
                        break;
                    case WindDdirection.West:
                        label_grass.Text = "/";
                        break;
                    case WindDdirection.Static:
                        label_grass.Text = "|";
                        break;
                }
            }
        }

        private void HewenqiTianyi_HoverTreeWindEvent(WindEventArgs ev)
        {
            UpdateLabel(ev.WindType);
        }
    }
}

HoverTreeForm窗体代码:

using System.Windows.Forms;

namespace TianYiHeWenQi
{
    public partial class HoverTreeForm : Form
    {
        public HoverTreeForm()
        {
            InitializeComponent();

            for (int i = 0; i < tableLayoutPanel_hovertree.ColumnCount; i++) {
                for (int j = 0; j < tableLayoutPanel_hovertree.RowCount; j++) {
                    tableLayoutPanel_hovertree.Controls.Add(new HoverTreeGrass(), i, j);
                }
            }
            HewenqiTianyi h_ty = new HewenqiTianyi();

        }
    }
}

TianYiHeWenQi项目源码下载

时间: 2024-08-27 21:56:56

C#自定义事件模拟风吹草摇摆的相关文章

js原生创建模拟事件和自定义事件的方法

让我万万没想到的是,原来<JavaScript高级程序设计(第3版)>里面提到的方法已经是过时的了.后来我查看了MDN,才找到了最新的方法. 1. 模拟鼠标事件 MDN上已经说得很清楚,尽管为了保持向后兼容MouseEvent.initMouseEvent()仍然可用,但是呢,我们应该使用MouseEvent().我们使用如下页面做测试 1 <!DOCTYPE html> 2 <html> 3 <head lang="zh-CN"> 4

javascript和jquey的自定义事件小结

“通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率.” 可以把多个关联但逻辑复杂的操作利用自定义事件的机制灵活地控制好 对象之间通过直接方法调用来交互 1)对象A直接调用对象B的某个方法,实现交互:直接方法调用本质上也是属于一种特殊的发送与接受消息,它把发送消息和接收消息合并为一个动作完成: 方法调用方和被调用方被紧密耦合在一起:因为发送消息和接收消息是在一个动作内完成,所以无法做到消息的异步发送和接收: 2)对象A生成消息->将消息通知给一个事件消息处理器(Obs

jQuery基础(鼠标事件,表单事件,键盘事件,自定义事件 篇)

1.jQuery鼠标事件之click与dbclick事件 方法一:$ele.click()(不带参数) <div id="test">点击触发<div> $("ele").click(function(){ alert('触发指定事件') }) $("#test").click(function(){ $("ele").click() //手动指定触发事件 });   方法二:$ele.click( h

自定义事件 (jQuery)

1jQuery自定义事件之trigger事件 众所周知类似于mousedown.click.keydown等等这类型的事件都是浏览器提供的,通俗叫原生事件,这类型的事件是需要有交互行为才能被触发. 在jQuery通过on方法绑定一个原生事件 $('#elem').on('click', function() { alert("触发系统事件") }); alert需要执行的条件:必须有用户点击才可以.如果不同用户交互是否能在某一时刻自动触发该事件呢? 正常来说是不可以的,但是jQuery

javascript事件之:谈谈自定义事件(转)

http://www.cnblogs.com/pfzeng/p/4162951.html 对于JavaScript自定义事件,印象最深刻的是用jQuery在做图片懒加载的时候.给需要懒加载的图片定义一个appear事件.当页面图片开始出现时候,触发这个自定义的appear事件(注意,这里只触发一次). 由此,现在我们通过JavaScript谈一谈自定义事件. 所谓事件,说的明白点,就是在一个合适的时候触发调用某个函数.平常说的事件是那些比较常用的,绑定在元素身上的某个方法,当用户触发某个行为时,

JavaScript实现自定义对象的自定义事件

前言: 大家都知道,在使用JavaScript可以很方便的使用addEventListener函数给DOM对象快速绑定一个或多个事件侦听器. 我们又如何在JavaScript的自定义对象中使用此方法并触发事件呢?这就是本章节的核心内容了. 目的: 现在有一个需求,要求"a对象"能够让"b对象"做一系列动作. 分析后我们得知.首先,"b对象"有一个固定名称作为入口让a对象调用,并且这个入口可以自动检索所有符合这个动作要求的函数并依次触发. 实现:

详解javascript实现自定义事件

这篇文章主要为大家介绍了javascript实现自定义事件的方法,自定义事件,顾名思义,就是自己定义事件类型,自己定义事件处理函数,javascript如何实现自定义事件,需要了解的朋友可以参考下 我们平时在操作dom时候经常会用到onclick,onmouseover等一系列浏览器特定行为的事件, 那么自定义事件,顾名思义,就是自己定义事件类型,自己定义事件处理函数,在合适的时候需要哪个事件类型,就去调用哪个处理程序 1.js所支持的浏览器默认事件 浏览器特定行为的事件,或者叫系统事件,js默

Dom3级事件下自定义事件

原文出处:  http://www.w3cfuns.com/notes/11861/e21736a0b15bceca0dc7f76d77c2fb5a.html . 我拿出作者中的一段,感谢作者原创. DOM中的事件模拟(自定义事件): DOM3级还定义了自定义事件,自定义事件不是由DOM原生触发的,它的目的是让开发人员创建自己的事件.要创建的自定义事件可以由createEvent("CustomEvent"); 返回的对象有一个initCustomEvent()方法接收如下四个参数.

跨浏览器 HTML5 postMessage 方法以及 message 事件模拟实现

postMessage 是 HTML5 新方法,它可以实现跨域窗口之间通讯.到目前为止,只有 IE8+, Firefox 3, Opera 9, Chrome 3和 Safari 4 支持,而本篇文章主要讲述 postMessage 方法与 message 事件跨浏览器实现. postMessage 方法 JSONP 技术不一样,前者是前端擅长跨域文档数据即时通讯,后者擅长针对跨域服务端数据通讯,postMessage 应用场景能说明这个区别: 应用场景举例 webOS 使用 iframe 嵌入