首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ASP.NET AJAX(13)__利用Microsoft AJAX Library开发客户端组件Sys.Component成员Sys.IDisposable成员Sys.INotifyDisposin

ASP.NET AJAX(13)__利用Microsoft AJAX Library开发客户端组件Sys.Component成员Sys.IDisposable成员Sys.INotifyDisposin

作者头像
小白哥哥
发布2018-03-07 11:32:07
3K0
发布2018-03-07 11:32:07
举报
文章被收录于专栏:技术小讲堂技术小讲堂

Microsoft AJAX Library定义了一个客户端组件的模型,它的基类是Sys.Component,它实现了三个接口Sys.IDisposable,Sys.INotifyDisposing,Sys.INotifyPropertyChange

Sys.Component成员

  • get_events()
  • get_id();
  • set_id();
  • get_isInitialized();
  • initialize();
  • dispose();
  • raisePropertyChanged();

Sys.IDisposable成员

  • dispose();

Sys.INotifyDisposing成员

  • add_disposing();
  • remove_disposing();

Sys.INotifyPropertyChange成员

  • add_propertyChanged();
  • remove_propertyChanged();

可视组件和不可视组件

可视组件,就是对DOM进行了封装,在Microsoft AJAX Library中可分为两种Sys.UI.Control和Sys.UI.Behavior,不可视组件不继承于Control和Behavior,它是一种辅助对象

Control和Behavior

  • Sys.UI.Control:封装了DOM元素,概念上为一个组合的控件
  • Sys.UI.Behavior:扩展了DOM元素,为DOM元素提供了额外的功能

全局容器

  • Sys._Application为一个全局的容器类
  • 维护着全局的所有Component对象的生命周期

客户端生命周期

TM截图未命名
TM截图未命名

这里的声明周期,很像我们的c#语言,实际上,它就是按照这种高级语言的声明周期来开发的,如果我们要创建对象,需要在Sys.Application.init事件中创建,并且调用Component的initialize方法,这样在load事件中,就可以在代码中控制它,这以为着,在Sys.Application的load阶段,所有的组件已经必须准备好

一个客户端与组件生命周期的示例

首先创建一个名为SimpleComponent.js的文件

/// <referenct name="MicrosoftAjax.js"/>

Type.registerNamespace("Demo");//注册一个命名空间

Demo.SimpleComponent = function() {
    Demo.SimpleComponent.initializeBase(this);//调用父类的构造函数
}

Demo.SimpleComponent.prototype =//添加成员
{
    initialize: function() {
        Demo.SimpleComponent.callBaseMethod(this, "initialize"); //调用父类名为initialize的方法
        alert("I've been initialized!");
    },
    dispose: function() {
        alert("I'm being disposed!");
        Demo.SimpleComponent.callBaseMethod(this, "dispose");
    },
    sayHi: function() {
        alert("Hello,i'm you first component!");
    }
}

Demo.SimpleComponent.registerClass("Demo.SimpleComponent", Sys.Component);//注册这个类,继承自Sys.Component

然后创建一个aspx页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SimpleLifeCycle.aspx.cs" Inherits="Demo12_SimpleLifeCycle" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Demo12/SimpleComponent.js" />
            </Scripts>
        </asp:ScriptManager>
        
        <script language="javascript" type="text/javascript">
            function pageInit() {
                alert("Page is initializaing!");
                $create(//Microsoft AJAX Library提供的创建对象的简单方法
                    Demo.SimpleComponent,//第一个参数,构造组件的类型
                    { "id": "simpleComponent" },//第二个参数,设置属性,这里只设置一个id
                    { "disposing": onDisposing });//第三个参数,设置事件
            }

            function pageLoad() {//页面加载完成后被调用
                var simple = $find("simpleComponent"); //找到simpleComponent这个组件
                simple.sayHi();//调用组件的sayHi方法
            }
            
            function onDisposing() {//Component释放的时候被调用
                alert("Component is being disposed");
            }

            Sys.Application.add_init(pageInit); //把pageInit方法添加到Sys.Application的init事件中,这样在Sys.Application的init事件中方法被调用
        </script>
    </form>
</body>
</html>

我们打开这个页面,一步一步的观察调用步骤

1.Sys.Application.init事件被触发

1
1

2.Component的initialize被调用

2
2

3.pageLoad被调用Component的sayHi方法被执行

3
3

4.离开页面,组件的dispose方法被调用

4
4

5.我们已经在创建对象的时候响应了对象的disposing事件,onDisposing方法被执行

5
5

开发一个Component

  • Sys.Component类(非必须)
  • 在构造函数里定义私有变量(将变量设置为默认值)
  • 覆盖initialize方法,初始化所有私有变量
  • 覆盖dispose方法,释放所有私有变量,避免资源泄漏
  • 定义其他成员
一个简单的Component的示例

创建一个名为Timer.js的文件

Type.registerNamespace("Demo");

Demo.Timer = function() {
    Demo.Timer.initializeBase(this);//调用基类构造函数
    this._interval = 1000;//私有变量设置为默认值
    this._timer = null; //私有变量设置为默认值
}

Demo.Timer.prototype =
{
    get_interval: function() {
        return this._interval;
    },
    set_interval: function(value) {
        if (this._interval != value) {//判断现在已有interval的值,是否等于要设置的值
            this._interval = value;
            this.raisePropertyChanged("interval");//告诉外接interval属性被改变
            if (this._timer) {
                this.stop();
                this.start();
            }
        }
    },
    add_tick: function(handler) {
        this.get_events().addHandler("tick", handler);//添加一个事件tick为事件名
    },
    remove_tick: function(handler) {
        this.get_events().removeHandler("tick", handler); //去除一个事件tick为事件名
    },
    _timerCallback: function() {
        var handler = this.get_events().getHandler("tick");//得到我们设置的事件
        if (handler) {//如果这个事件存在
            handler(this, Sys.EventArgs.Empty);
        }
    },
    start: function() {
        if (this._interval > 0) {
            this._timer = window.setInterval(//这里使用的是javascript的原生方法
                Function.createDelegate(this, this._timerCallback), //使_timerCallback的指针指向组件本身,而不是window
                this._interval);
        }
    },
    stop: function() {
        if (this._timer) {//如果_timer已经被赋值,证明已经开始啦
            window.clearInterval(this._timer);
            this._timer = null;
        }
    }
}

Demo.Timer.registerClass("Demo.Timer", Sys.Component);

创建一个aspx页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Timer.aspx.cs" Inherits="Demo12_Timer" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Demo12/Timer.js" />
            </Scripts>
        </asp:ScriptManager>
        
        Interval:
        <input type="text" value="1000" id="txtInterval" />
        <input type="button" value="Change" onclick="changeInterval()" /><br />
        
        <div id="display"></div>
        
        <script language="javascript" type="text/javascript">
            Sys.Application.add_init(function() {
            $create(Demo.Timer,//创建这个Component
                { "id": "timer" },//定义一个ID
                { "tick": onTick, "propertyChanged": onPropertyChanged });//创建事件处理程序
            });

            function onPropertyChanged(sender, args) {//propertyChanged被触发的时候,此方法被调用
                var property=args.get_propertyName();//得到改变属性的名称
                var value = sender["get_" + property].apply(sender);//apply指定指针指向组件对象
                alert(property+" is changed to "+value);
            }
            
            window.counter = 0;//一个计数器

            function onTick() {//组件的tick事件被触发时,此方法被调用
                $get("display").innerHTML = window.counter++;
            }

            function pageLoad() {//页面加载完成,timer开始工作
                $find("timer").start();
            }

            function changeInterval() {
                $find("timer").set_interval(
                    parseInt($get("txtInterval").value, 10));
            }
        </script>
    </form>
</body>
</html>

这里就使用到了我们创建的Component,实现一个计数器的效果,类似一个客户端的Timer

Sys.Component成员

  • events只读属性//事件集合
  • id属性//组件的id
  • initialize方法
  • isInitialized只读属性//是否在构造中
  • raisePropertyChanged方法//告诉外界哪个属性改变
  • propertyChanged事件//属性改变后触发
  • dispose方法
  • disposing事件
  • beginUpdate方法//开始Update
  • isUpdating只读属性//是否处于Update状态
  • endUpdate方法
  • updated方法

组件处于正在更新的状态称为Update状态,处于更新状态时候组件的数据可能出于不一致的状态,因此,出于更新状态的组件,允许组件处于不一直的状态,但是应该尽量避免与外接的交换,尤其是处于DOM元素有关的交互,有时候,合理的利用Update状态也能够在一定程序上提高性能

Update状态的使用

  • Sys.Component._setProperties方法:批量修改组件的属性(在非Update状态下)(调用beginUpdate方法->设置组件属性->调用endUpdate方法)

Update状态在系统中的使用

windows的DOM事件load被触发

           Sys.Application对象的beginCreatComponent方法被调用

           SysApplication对象的Init事件被触发

                   $Creat方法被调用,用于创建对象

                        组件的beginUpdate方法被调用

                        部分组件的endUpdate方法被调用

                             如果他们还没有被初始化,而initialize方法被调用

                             他们的Updated方法被调用

          Sys.Application对象的endCreatComponent方法被调用

               剩余组件的endUpdate方法被调用

开发时Update状态的使用方式

  1. 调用beginUpdate方法
  2. 修改属性
  3. 调用endUpdate方法,此外,经常重写Updated方法,提交组件更新信息
一个改进版的Timer示例

创建一个名为BetterTimer.js的文件

/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("Demo");

Demo.Timer = function() {
    Demo.Timer.initializeBase(this);
    this._interval = 1000;
    this._enabled = false;
    this._timer = null;
}

Demo.Timer.prototype =
{
    add_tick: function(handler) {
        this.get_events().addHandler("tick", handler);
    },
    remove_tick: function(handler) {
        this.get_events().removeHandler("tick", handler);
    },
    _timerCallback: function() {
        var handler = this.get_events().getHandler("tick");
        if (handler) {
            handler(this, Sys.EventArgs.Empty);
        }
    },
    _startTimer: function() {
        this._timer = window.setInterval(
          Function.createDelegate(this, this._timerCallback),
          this._interval);
    },
    _stopTimer: function() {
        window.clearInterval(this._timer);
        this._timer = null;
    },
    get_interval: function() {
        return this._interval;
    },
    set_interval: function(value) {
        if (this._interval != value) {
            this._interval = value;
            this.raisePropertyChanged("interval");
            if (!this.get_isUpdating() && this._timer != null) {//timer正在执行,而且组件不出于Update状态
                this._stopTimer();
                this._startTimer();
            }
        }
    },
    updated: function() {//重写父类的updated方法
        Demo.Timer.callBaseMethod(this, "updated");//调用父类的updated方法
        this._stopTimer();
        if (this._enabled) {
            this._startTimer();
        }
    },
    get_enabled: function() {
        return this._enabled;
    },
    set_enabled: function(value) {
        if (value != this._enabled) {
            this._enabled = value;
            this.raisePropertyChanged("enabled");

            if (!this.get_isUpdating()) {//不出于更新状态
                if (value) {
                    this._startTimer();
                }
                else {
                    this._stopTimer();
                }
            }
        }
    },
    dispose: function() {
        this.set_enabled(false);
        this._stopTimer();
        Demo.Timer.callBaseMethod(this, "dispose");
    }
}

Demo.Timer.registerClass("Demo.Timer", Sys.Component);

创建一个aspx的页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BetterTimer.aspx.cs" Inherits="Demo12_BetterTimer" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Demo12/BetterTimer.js" />
            </Scripts>
        </asp:ScriptManager>
        
        Interval:<input type="text" value="1000" id="txtInterval" /><br />
        <input type="checkbox" id="chkEnabled" checked="checked" />
        <label for="chkEnabled">Enabled</label><br />
        <input type="button" value="Change" onclick="changeStatus()" />
        <hr />
        <div id="display"></div>
        <script language="javascript" type="text/javascript">
            Sys.Application.add_init(function() {
                $create(Demo.Timer,
                    { "id": "timer", "enabled": true },
                    { "tick": onTick });
                });
            window.counter = 0;
            function onTick() {
                $get("display").innerHTML = window.counter++;
            }

            function changeStatus() {
                var timer = $find("timer");
                timer.beginUpdate();
                timer.set_interval(parseInt($get("txtInterval").value, 10));
                timer.set_enabled($get("chkEnabled").checked);
                timer.endUpdate();
            }
            
        </script>
    </form>
</body>
</html>

Control模型(可视化组件模型)

  • 封装一个DOM元素
  • 提供统一的开发模型
  • 可以用于开发复杂组件
  • 构造函数接受一个element参数,表示这个组件封装的DOM元素

Sys.UI.Control类成员

  • element只读属性//要封装的元素
  • visibilityMode属性//枚举:hide(0)相当于style.visibility,collapse(1)相当于style.display
  • visable属性//bool,可见性
  • addCssClass方法//添加一个class样式
  • removeCssClass方法//去除一个class样式
  • toggleCssClass方法//如果没有一个class样式,而添加,如果有则去除
  • parent属性//
  • onBubbleEvent方法
  • raiseButtleEvent方法
一个使用Control模型的示例

创建一个名为TextBox.js的文件

/// <reference name="MicrosoftAjax.js"/>

Type.registerNamespace("Demo");
Demo.TextBox = function(element) {//注意这里有一个参数,是要封装的DOM元素
    Demo.TextBox.initializeBase(this, [element]);
    this._originalText = null;//保存元素中原先有的值
}

Demo.TextBox.prototype =
{
    initialize: function() {
        Demo.TextBox.callBaseMethod(this, "initialize"); //调用父类方法
        //响应文本框的change事件
        $addHandler(this.get_element(), "change",
            Function.createDelegate(this, this._onTextChange));
    },
    _onTextChange: function(e) {
        if (this.get_isUpdating()) {
            return;
        }
        var handler = this.get_events().getHandler("textChange");
        if (handler) {
            var args = new Sys.CancelEventArgs();
            handler(this, args);

            if (args.get_cancel()) {
                this.beginUpdate(); //这样做,是为了设置文本框的text改变的时候,又会触发一个textChange事件
                this.set_text(this._originalText);
                this.endUpdate();
            }
        }
        this._originalText = this.get_element().value;
    },
    add_textChange: function(handler) {
        this.get_events().addHandler("textChange", handler);
    },
    remove_textChange: function(handler) {
        this.get_events().removeHandler("textChange", handler);
    },

    //一个text属性
    get_text: function() {
        return this.get_element().value; //get_element方法,返回封装的DOM元素
    },
    set_text: function(value) {
        if (value != null) {
            this.get_element().value = value;
        }
        else {
            this.get_element().value = "";
        }
    }
}

Demo.TextBox.registerClass("Demo.TextBox", Sys.UI.Control);

创建一个aspx页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TextBox.aspx.cs" Inherits="Demo12_TextBox" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Demo12/TextBox.js" />
            </Scripts>
        </asp:ScriptManager>
        
        <input type="text" id="textBox" />
        
        <script language="javascript" type="text/javascript">
            Sys.Application.add_init(function() {
            $create(Demo.TextBox,//创建的组件类型
                 null,//这里不设置ID
                { "textChange": onTextChange },//响应事件
                null,
                $get("textBox"));//需要封装的元素
            });

            function onTextChange(sender, args) {
                var message = String.format("The text would be changed to '{0}',are you sure?", sender.get_text());
                if (!confirm(message)) {
                    args.set_cancel(true);//确定“取消操作”
                }
            }
        </script>
    </form>
</body>
</html>

这样,我们实现了文本在改变以后,提示用户是不是确定操作,如果不确定这次操作,则可以撤销这次操作,注意,textChange是在改变文本后,焦点离开文本框以后触发的

我们使用这个组件,对一个普通的textbox进行的封装,这就是一个Control模型的使用示例

$creat方法

  • 原型:$creat(type,properties,events,references,element);
  • referencts是一个字典,保存对象属性与其他对象的关系,key为属性名,value为其他对象id
  • 保证initialize方法调用时,属性已经被设置为所需要的对象,几十调用$creat方法时,其他对象还没有创建

复合控件

复合控件主要会涉及到Control模型中的以下两个方法

  • raiseBubbleEvent(source,args);//由子控件调用,将触发的事件向父控件传递
  • onBubbleEvent(source,args);//父控件重写该方法,用于接受子控件向上传递过来的事件

这两个方法的主要作用是降低父控件和子控件之间的耦合关系,例如子控件不需要知道它的父控件是谁,只需要调用这个方法,把触发的事件向上传递就好啦,至于由谁来接受,这属于另外一个控件的设计啦

一个复合控件的示例

创建一个名为ButtonList.js的文件

/// <reference name="MicrosoftAjax.js"/>

Type.registerNamespace("Demo");

Demo.Button = function(element) {
    Demo.Button.initializeBase(this, [element]);

    this._context = null;//上下文对象,用于保存控件的一些信息
    this._onClickHandler = null;//click事件的监听器
}

Demo.Button.prototype =
{
    initialize: function() {
        Demo.Button.callBaseMethod(this, "initialize");//调用基类方法
        this._onClickHandler = Function.createDelegate(this, this._onClick);
        $addHandler(this.get_element(), "click", this._onClickHandler);
    },
    //释放资源,防止资源泄漏
    dispose: function() {
        this._onClickHandler = null;
        $clearHandlers(this.get_element());
        Demo.Button.callBaseMethod(this, "dispose");
    },
    //元素点击后会调用
    _onClick: function(e) {
        var eventArgs = new Demo.ButtonClickEventArgs(this._context);
        this.raiseClick(eventArgs);
    },
    
    //context属性
    get_context: function() {
        return this._context;
    },
    set_context: function(value) {
        this._context = value;
    },
    //把事件向上传递
    raiseClick: function(args) {
        this.raiseBubbleEvent(this, args);
    }
}

Demo.Button.registerClass("Demo.Button", Sys.UI.Control);//注意,继承自Sys.UI.Control


//自定义的EventArgs
Demo.ButtonClickEventArgs = function(context) {
    Demo.ButtonClickEventArgs.initializeBase(this);
    this._context = context;
}
Demo.ButtonClickEventArgs.prototype =
{
    get_context: function() {
        return this._context;
    }
}

Demo.ButtonClickEventArgs.registerClass("Demo.ButtonClickEventArgs", Sys.EventArgs);//继承自Sys.EventArgs



Demo.ButtonList = function(element) {
    Demo.ButtonList.initializeBase(this, [element]);
    this._itemDataList = null;//存储组件内包含的组件对象
}

Demo.ButtonList.prototype =
{
    initialize: function() {
        Demo.ButtonList.callBaseMethod(this, "initialize");
        for (var i = 0; i < this._itemDataList.length; i++) {
            this._createNewButton(this._itemDataList[i]);
        }
    },
    _createNewButton: function(data) {
        var buttonElement = document.createElement("input");//创建一个Input元素
        buttonElement.type = "button";//元素的type为button(按钮)
        buttonElement.value = data.text;//按钮上的文字
        this.get_element().appendChild(buttonElement);//按钮添加到这个组件上
        
        //把创建的元素,用上面定义的组件进行封装
        $create(Demo.Button,
            { "context": data.context, "parent": this },//指定父控件为自身(ButtonList)
            null, null, buttonElement);
    },
    get_itemDataList: function() {
        return this._itemDataList;
    },
    set_itemDataList: function(value) {
        this._itemDataList = value;
    },
    //当有事件被传递上来的时候调用
    onBubbleEvent: function(source, e) {
        this.raiseItemClick(e);
        return true;//表示事件已经被处理掉了,不需要向上传递
    },
    add_itemClick: function(handler) {
        this.get_events().addHandler("itemClick", handler);
    },
    remove_itemClick: function(handler) {
        this.get_events().removeHandler("itemClick", handler);
    },
    raiseItemClick: function(args) {
        var handler = this.get_events().getHandler("itemClick");
        //如果有这个事件
        if (handler) {
            handler(this, args);
        }
    }
}

Demo.ButtonList.registerClass("Demo.ButtonList", Sys.UI.Control);

然后,创建一个aspx页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ButtonList.aspx.cs" Inherits="Demo12_ButtonList" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Path="~/Demo12/ButtonList.js" />
            </Scripts>
        </asp:ScriptManager>
        
        <div id="buttonList"></div>
        
        <script language="javascript" type="text/javascript">
            Sys.Application.add_init(
                function() {
                    var datalist =
                    [
                        {
                            text: "Item1",
                            context: "Item 1 has been clicked!"
                        },
                        {
                            text: "Item2",
                            context: "Item 2 has been clicked!"
                        },
                        {
                            text: "Item3",
                            context: "Item 3 has been clicked!"
                        }
                    ];
                    $create(Demo.ButtonList,//组件类型
                        { "itemDataList": datalist },//指定属性
                        { "itemClick": onItemClick },//响应事件
                        null,
                        $get("buttonList"));//要封装的元素
                }
            );

                function onItemClick(sender, args) {
                    alert(args.get_context());//得到args的context属性
                }
        </script>
    </form>
</body>
</html>

运行页面,我们点击按钮就会看到弹出的结果,注意,这里的click事件虽然是子控件(Button)发起的,但是最后处理它的是我们创建的复合控件(ButtonList),这就是我们的raiseBubbleEvent方法和onBubbleEvent方法的功能和它们的使用方法

Behavior模型

  • 另外一种可视化组件模型,继承与Sys.UI.Behavior
  • Control包装DOM元素,Behavior为DOM元素提供功能
  • 一个DOM元素智能由一个Control来包装,但是可以使用多个Behavior进行装饰

Behavior成员

  • 与Component组件相比唯一增加的属性是name
  • 由于一个M元素上可以添加多个Behavior,因此如果要通过元素获得Behavior对象就需要通过name属性获得
  • $get("elementId")["name_of_behavior"]
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-10-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sys.Component成员
  • Sys.IDisposable成员
  • Sys.INotifyDisposing成员
  • Sys.INotifyPropertyChange成员
  • 可视组件和不可视组件
  • Control和Behavior
  • 全局容器
  • 客户端生命周期
  • 开发一个Component
  • Sys.Component成员
  • Update状态的使用
  • Update状态在系统中的使用
  • 开发时Update状态的使用方式
  • Control模型(可视化组件模型)
  • Sys.UI.Control类成员
  • $creat方法
  • 复合控件
  • Behavior模型
    • Behavior成员
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档