Android如何在自定义view中发送消息给主线程

求求各位大神支招,小弟在自己开发一个东西,遇到了一个小问题。
![图片说明

图片说明](https://img-ask.csdn.net/upload/201603/15/1458054689_616589.jpg)

我在自定义view的onDraw里,当条件达到后就开启一个子线程发送消息给主线程,让主线程中的handler接收消息并执行相应的动作,可是在Log的输出下只能输出“子线程,”而没有”handlemessage“,并且异常退出,退出代码如下:
03-15 22:50:34.593: W/dalvikvm(27492): threadid=1: thread exiting with uncaught exception (group=0x41c6ece0)
03-15 22:50:34.593: W/dalvikvm(27492): threadid=1: uncaught exception occurred
03-15 22:50:34.593: W/System.err(27492): java.lang.NullPointerException
03-15 22:50:34.593: W/System.err(27492): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:4094)
03-15 22:50:34.593: W/System.err(27492): at android.os.Handler.dispatchMessage(Handler.java:110)
03-15 22:50:34.593: W/System.err(27492): at android.os.Looper.loop(Looper.java:193)
03-15 22:50:34.593: W/System.err(27492): at android.app.ActivityThread.main(ActivityThread.java:5348)
03-15 22:50:34.593: W/System.err(27492): at java.lang.reflect.Method.invokeNative(Native Method)
03-15 22:50:34.593: W/System.err(27492): at java.lang.reflect.Method.invoke(Method.java:515)
03-15 22:50:34.593: W/System.err(27492): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
03-15 22:50:34.594: W/System.err(27492): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
03-15 22:50:34.594: W/System.err(27492): at dalvik.system.NativeStart.main(Native Method)
03-15 22:50:34.594: W/dalvikvm(27492): threadid=1: calling UncaughtExceptionHandler
03-15 22:50:34.594: I/dalvikvm(27492): +++ calling Ljava/lang/ThreadGroup;.uncaughtException
03-15 22:50:34.594: D/dalvikvm(27492): threadid=11: bye!
03-15 22:50:34.595: E/AndroidRuntime(27492): FATAL EXCEPTION: main
03-15 22:50:34.595: E/AndroidRuntime(27492): Process: com.example.wyccustomview3, PID: 27492
03-15 22:50:34.595: E/AndroidRuntime(27492): java.lang.NullPointerException
03-15 22:50:34.595: E/AndroidRuntime(27492): at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:4094)
03-15 22:50:34.595: E/AndroidRuntime(27492): at android.os.Handler.dispatchMessage(Handler.java:110)
03-15 22:50:34.595: E/AndroidRuntime(27492): at android.os.Looper.loop(Looper.java:193)
03-15 22:50:34.595: E/AndroidRuntime(27492): at android.app.ActivityThread.main(ActivityThread.java:5348)
03-15 22:50:34.595: E/AndroidRuntime(27492): at java.lang.reflect.Method.invokeNative(Native Method)
03-15 22:50:34.595: E/AndroidRuntime(27492): at java.lang.reflect.Method.invoke(Method.java:515)
03-15 22:50:34.595: E/AndroidRuntime(27492): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:829)
03-15 22:50:34.595: E/AndroidRuntime(27492): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:645)
03-15 22:50:34.595: E/AndroidRuntime(27492): at dalvik.system.NativeStart.main(Native Method)

0

8个回答

1

eventbus可以?

0

我感觉这样比较好
1.在主线程中创建handler对象覆盖其handlemessage方法
2.在你这个自定义的view的构造方法中传入这个handler对象
3.然后在这个view的任何一个地方都可以调用这个handler的sendmessage方法,不需要开启一个新的线程

0
qq_21923871
Change_HDB 回复wyc123123: 我突然感觉你的这个View就是主线程,不知道对不对
3 年多之前 回复
wyc123123
wyc123123 view里不是有个getHandler函数吗,它是获取该view运行所在的线程的Handler的
3 年多之前 回复

你可以查看下handler的用法, 可以使用handle中的sendmessage方法发送message给主线程。

0
wyc123123
wyc123123 没有用啊,我就是这样的
3 年多之前 回复

//getHandler().sendEmptyMessage(FROM_CUSTOMVIEW);
问题就出现在子线程中的这句,注释掉后就没事了

0

首先报的是空指针,你可以尝试着不要写匿名类, 写一个Thread类, 然后写一个Handler类 使用Thread类的构造方法传参进入。
Message m = new Message(); m.what =?; 或者 m.obj = 一个对象; 最后使用handler.sendMessage(m)发送;当然Handler是内部类 可以直接使用Activity中的所有内部变量。

0

Activity中使用方法
Handler mh = new Auhandler();
Thread checkUser = new Thread(new CheckUser(mh));
checkUser.start();

private class Auhandler extends Handler{
public void handleMessage(Message msg)

{
//这里处理msg数据,内部类可以直接调用Activity中的所有属性与方法。
}
}

private class CheckUser implements Runnable{
Handler mh = null;
public CheckUser(Handler mh){
this.mh = mh;

}
public void run() {
Message m = new Message();
m.what = 0; //传送一个Int数据
m,what = new Object(); //可以传送任意对象,到handleMessage中是 可以通过 强转 msg.obj 取得对象。
this.mh.sendMessage(m);
}
}

0

首先子线程不能操作主线程
getHandler().sendEmptyMessage(FROM_CUSTOMVIEW);上面已经提到的

0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
Android子线程给主线程发送消息
Android线程机制和Java几乎一样,基本用法还是有两种 新建一个类继承Thread类 实现Runnable接口的方式定义一个线程 两种方法都需要覆写run方法,并用start方法启动 1.new MyTread().start(); 2.new Thread(myThread).start();Thread的构造函数接收一个runnable参数,new出的 MyThread正是一个实现Ru
android 主线程给子线程发送消息
这是我自己写的demo,练习在android中主线程给子线程发送消息
如何在主线程中,给子线程使用POSTMESSAGE发送消息?
子线程给主线程发送没有问题,但反过来,行吗?,我试了试,好像没有作用!rnrn请教高手指点!谢谢
主线程给子线程发送消息
/创建一个子线程,用于主线程向子线程发送消息 class MyThread extends Thread { Handler handler=null; public Handler getHandler(){ return handler; } @Override public void run() { //当子线程给主线程发
Android主线程给多个线程发送消息
经过探索,我发现可以实现一个主线程给多个线程发送消息,主线程接收每个线程的内容进行处理 下面是我改造的例子:
如何给View发送消息
如何在自己开的线程中,给View发送消息
android 子线程向主线程发送消息
利用Looper.getMainLooper()方法获得一个主线程的Looper,通过抓线程的looper实例一个主线程的handler new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { }
Android中的自定义View
自定义View 理解MeasureSpec View的工作流程 measure过程 View的measure过程 继承View重写onDraw方法 自定义属性提供给外界自定义View自定义View三步走: mesure: View的测量流程 layout: 布局流程 draw: 绘制流程 mesure:用来测量View的宽和高 layout:确定View在父容器中放置位置 draw:负责将Vie
Android中自定义View
先说一下自定义控件特点1、特定的显示风格 2、处理特有的用户交互 3、优化布局 4、封装自定义控件步骤1、自定义属性的声明与获取 1)分析需要的自定义属性 2)在res/values/attrs.xml定义声明 3)在layout.xml文件中进行使用 4)在View的构造方法中通过context.obtainStyledAttributes()得到的一个TypedArr
Android中自定义view
最近在学习自定义view,对RectF进行了解读,首先我们把// 将画布移到屏幕中央canvas.translate(200, 200);就有了如下的图片 通过上图知道这些代表的什么意思,以及Rectf也有一定的了解,举例,假如我们在第四象限有个矩形,其 left, top,right,bottom为50,-50,100,-100,我怎样把他移到第二象限呢?其实很简单,Rectf中里面参数是
android中自定义View
View 的基本概念这个类是用户接口的基础构件。 View 表示屏幕上的一块矩形区域,负责绘制这个区域和事件 处理。 View 是所有widget类的基类,Widget 类用于创建交互式UI构件(按钮,输入框等)。 View 类的ViewGroup子类是layout的基类,Layout是一个不可见的容器,它保存着 View(或ViewGroup)并定义这些View的layout属性。 可以
如何在android studio中实现自定义view
一、首先新建一个项目,项目及名称自拟。 二、在app上点击右键->new->Module  选择android library。比如在我的例子中我取名为topbar。 三、在topbar下的values中新建一个attrs.xml文件,用来存放自定义view的属性。 4.在topbar下实现view。 5.上面两部做完后就是引用这个view,这里需要注意的是要在主app的build
如何在DDK中发送消息
如何在DDK中发送消息?rn有资料上说RegisterWindowMessage, 再SendNotifyMessage,rn可是DDK中如何调用这些API?头文件?
工作线程发送消息给View的实现
我现在要从工作线程中发送消息给一个ListView,工作线程是个全局函数,ListView是切分窗口的右半部分,请问各位高手:如何获得ListView的句柄?
如何在一个View类中向另一个View发送消息
在一个View中怎么对另一个view使用PostMessage?
如何在子线程中向主线程发送消息,让主线程结束,程序中止。
下面一段代码是借用站上一位朋友sadf的,程序实现的是一个telnet服务器程序,输入exit,客户端与服务器断开。我想加上一个,输入shutdown,telnet服务器程序退出。由于与客户端打交道的是telnet服务器产生的一个子线程,则应该由子线程接收quit命令,然后由该子线程向主线程发送消息,令主线程结束。rnrnrn//连接端口是4250,连接后没有回显,直接输密码123456就可以进去了。rnrn#include "stdafx.h"rn#include rn#include rnrn/*rnMyRecv的功能是在一个指定的套接字*psockid上接受最多buflen个字符rn到pbuf指向的缓冲区中,或是收到回车也返回,因为telnet是按一下键发一个字符的rn*/rnlong MyRecv(SOCKET *psockid=NULL,rn char *pbuf=NULL,rn const unsigned long buflen=0);rnrnDWORD WINAPI UserThread(SOCKET *UserSockid=NULL);rnrnconst char *baner = "\n\rAuthor:\tsjdf\n\rEmail:\tsjdf1@163.com\n\r\n\r";rnconst char *pwd = "123456";rnint pwdlen = strlen(pwd);rnrnint APIENTRY WinMain(HINSTANCE hInstance,rn HINSTANCE hPrevInstance,rn LPSTR lpCmdLine,rn int nCmdShow)rnrn // TODO: Place code here.rn rn const unsigned short myport = 4250;rn WSADATA wsadata;rn if (WSAStartup(MAKEWORD(2,0),&wsadata) != 0)rn rn return 1;rn rn rn SOCKET sockid = INVALID_SOCKET;rn if ((sockid = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)rn rn WSACleanup();rn return 1;rn rnrn sockaddr_in srv_addr;rn int addrlen = sizeof(srv_addr);rnrn srv_addr.sin_family = AF_INET;rn srv_addr.sin_addr.S_un.S_addr = INADDR_ANY;rn srv_addr.sin_port = htons(myport);rn memset(&srv_addr.sin_zero,0,8); rnrn if (bind(sockid,(sockaddr*)&srv_addr,addrlen) < 0)rn rn closesocket(sockid);rn WSACleanup();rn return 1;rn rnrn listen(sockid,3);rn SOCKET *msgsockid = NULL;rn DWORD threadid;rnrn while (true) //循环等待,如有新的连接请求就接收rn rn msgsockid = new SOCKET;rn *msgsockid = accept(sockid, (sockaddr*)&srv_addr,NULL);rn if (*msgsockid == INVALID_SOCKET)rn rn delete msgsockid;rn Sleep(1000);rn rn elsern rn if (CreateThread(0,rn 0,rn (LPTHREAD_START_ROUTINE)UserThread,rn msgsockid,rn 0,rn &threadid) == NULL)rn rn delete msgsockid;rn Sleep(1000);rn rn rn rnrn return 0;rnrnrnrnrnlong MyRecv(SOCKET *psockid,char *pbuf,const long buflen)rnrn memset(pbuf,0,buflen);rn long count = 0;rn dorn rn if (count >= buflen)rn rn return count;rn rnrn if (recv(*psockid,pbuf+count,1,0) < 0)rn rn return -1;rn rnrn while (pbuf[count++] != '\n');rnrn return count;rnrnrn//为每个用户使用这个线程创建shellrnrnDWORD WINAPI UserThread(SOCKET *UserSockid)rnrn char recvbuf[1024];rn char sendbuf[2048];rn const long recvbuflen = sizeof(recvbuf);rn const long sendbuflen = sizeof(sendbuf);rnrn unsigned long cmdtouserlen,usertocmdlen;rn rn HANDLE hClientReadPipe, hClientWritePipe;rn HANDLE hCmdWritePipe, hCmdReadPipe;rn rn PROCESS_INFORMATION processinfo;rn rn //接收口令rn if (MyRecv(UserSockid,recvbuf,recvbuflen) < 0)rn rn goto exit3;rn rnrn //验证口令rn if (memcmp(recvbuf,pwd,pwdlen) != 0)rn rn goto exit3;rn rn rn //发送登录Banerrn if (send(*UserSockid,baner,strlen(baner),0) < 0)rn rn goto exit3;rn rnrn //创建管道rn SECURITY_ATTRIBUTES pipeattr;rn pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES);rn pipeattr.lpSecurityDescriptor = NULL;rn pipeattr.bInheritHandle = TRUE;rnrn if (CreatePipe(&hClientReadPipe,rn &hCmdWritePipe,rn &pipeattr,rn 0) == 0)rn rn goto exit3;rn rnrn if (CreatePipe(&hCmdReadPipe,rn &hClientWritePipe,rn &pipeattr,rn 0) == 0)rn rn goto exit4;rn rnrn //启动cmd.exern STARTUPINFO startinfo;rn GetStartupInfo(&startinfo);rn startinfo.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;rn startinfo.hStdInput = hCmdReadPipe;rn startinfo.hStdError = hCmdWritePipe;rn startinfo.hStdOutput = hCmdWritePipe;rn startinfo.wShowWindow = SW_HIDE;rn rn char szAPP[256];rn GetSystemDirectory(szAPP,MAX_PATH+1);rnrn strcat(szAPP,"\\cmd.exe");rn if (CreateProcess(szAPP,rn NULL,rn NULL,rn NULL,rn true,rn 0,rn NULL, rn NULL,rn &startinfo,rn &processinfo) == 0)rn rn goto exit5;rn rn rn while(true)rn rn if (PeekNamedPipe(hClientReadPipe,rn sendbuf,rn sendbuflen,rn &cmdtouserlen,rn 0,rn 0) == 0)rn rn goto exit5;rn rnrn if(cmdtouserlen == 0)rn rn if ((usertocmdlen=MyRecv(UserSockid,recvbuf,recvbuflen)) < 0)rn rn goto exit5;rn rn rn if (memcmp(recvbuf,"exit",4) == 0)rn rn goto exit5;rn rnrn if (WriteFile(hClientWritePipe,rn recvbuf,rn usertocmdlen,rn &usertocmdlen,rn 0) == 0)rn rn goto exit5;rn rnrn Sleep(200);rn rn elsern rn memset(sendbuf,0,sendbuflen);rn if (ReadFile(hClientReadPipe,rn sendbuf,rn cmdtouserlen,rn &cmdtouserlen,0) == 0)rn rn goto exit5;rn rnrn if (send(*UserSockid,sendbuf,cmdtouserlen,0) == SOCKET_ERROR)rn rn goto exit5;rn rnrnrn rn rn rnexit5: CloseHandle(hCmdReadPipe);rnexit4: CloseHandle(hClientReadPipe);rnexit3: closesocket(*UserSockid);rnexit2: delete UserSockid; rnexit1: return 1;rnrn
线程发送消息到主线程的问题?
使用线程(多个)发送到主线程,并根据相应的消息,主窗体中的列表中显示不同的内容;rn使用SendMessage或PostMessage时主线程窗体运行正常,但是拖动主窗体时这些线程似乎都不运行了rn请问这是怎么回事,如何解决?rn经测试这些线程并没有结束。
Handler向主线程发送消息
Android studio连接网络时,新开的子线程需要读取网络图片信息,并将InputStream发送给主线程,查了下资料都是用sendMessage(); (我用时 用红线标注了,报错)为什么吗,难道弃用了吗?求大神解释。可以的话 希望慷慨贴点Handler发送和接受的代码 谢谢
Android主线程如何向分线程发送消息
Android主线程如何向分线程发送消息
Android中自定义View,自定义布局
这里主要用到两种自定义布局的方法,第一是使用inflate加载布局文件,也是最简单的,但是前提是要继承自ViewGroup,第二种是自定义View的方式是重写View的onMeasure(),onLayout(),onDraw方法,这种要稍微复杂一点。下面总结一下两种自定义View。 一、使用布局文件xml文件来自定义布局 首先定义定义一个View,继承自RelativeLayout,当然也可以
主线程向子线程发送消息
  public class TestHandler extends Activity {   Button m_startbtn ; Button m_endbtn; MyThreadHandler m_threadHandler;   /** Called when the activity is first created. */     @Override ...
Android中使用自定义View
一、自定义VIEW的详细步骤 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局——onLayout():决定View在ViewGroup中的位置 3.绘制——onDraw():如何绘制这个View。 一般自定义view需要遵循上面的步骤 二、Measure() Measure的中文意思就是测量。所以它的作用就
Android 中自定义View的应用.
大家好我们今天的教程是在Android 教程中自定义View 的学习,对于初学着来说,他们习惯了Android 传统的页面布局方式,如下代码:   view plain &amp;lt;?xml version= &quot;1.0&quot;  encoding= &quot;utf-8&quot; ?&amp;gt;   &amp;lt;LinearLayout xmlns:android=&quot;http:...
Android中的自定义View(一)
我们在实际开发过程中,如果想要在界面做出酷炫的效果,单单靠系统提供的控件是远远不够的,所以这时候就需要自定义View了。在Google下也有好多比较成熟的开源项目/开源控件可下载来使用,但是毕竟代码的设计都是原作者的思路,我们在使用起来也有可能受到意外的限制或多余功能的冗余。自己掌握自定义View的制作还是很有必要的,毕竟有时项目中还是可能需要独一无二的样式控件,而且自己通过自定义View绘制出来...
android中自定义的view和属性
该资源包含了一个android自定义的view和他的属性的简单的demo,包含了齐总的总结,简单易懂喜欢的下载!
Android中自定义View之流式布局
Android中自定义View之流式布局的Demo,代码中关键步骤并有注释原理解说,轻松掌握自定义View的onMeasure和onLayout的实现
Android中自定义View(1)
自定义View属性: 最近项目中经常需要用到自定义控件,因此自定义属性也是经常要用到的,在此说明一下自定义属性的用法: 自定义属性都存在于/value/attr.xml文件中,以如下格式存在。                                          ......              对于自定义属性中的format的值及其含义如下: form
android自定义loding view(中)
下面先上图: 暂时完成了一部分吧,支持loading图形和loading字颜色的改变,算法需要优化,内存不会溢出,但是感觉不好,下面上代码 view: package com.fanyafeng.orlitedemo.myview; import android.content.Context; import android.graphics.Canvas; import andr
Android子线程向主线程发送消息实现
在Android中开发应用的过程中,经常会遇到一些比较耗时的操作,比如网络请求、读取文件等操作。由于Android有一种ANR机制,UI线程阻塞超过5s就会报ANR错误。因此这些耗时的操作需要在子进程里去做。单起一个子线程去做耗时操作,可以解决ANR问题。但同时还有一个问题,就是子线程完成了操作,如何通知主线程即UI线程去做UI方面的更改。这就用到Handler。     此处讲解的是子线程
Android中初步自定义view
问题1 ,Paint画笔对象为null的异常 FATAL EXCEPTION: main Process: com.fang.zrf.mycustomview, PID: 12882 java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a
Android中如何自定义View
我们在做界面的时候发现界面中很多条条目目很相似,只是内容或背景不同,样式基本是一样的,导致开发者一直在重复写一样的代码,在我们看来完全可以作为一个View来使用,但是Android中又没有这样的View。当然我们可以使用ListView,但是它也并非条目数量太多,一般也不需要变动,而且别的界面也需要,我们更倾向于像使用普通View一样的使用方法,所以使用自定义控件比较方便。 首先我们需要为自定义
如何在自定义的View创建ImageButton
[color=#FF0000]不是在Activity里[/color],而是在View里创建ImageButton,如何实现?
android给自定义view添加XML属性
1.在value下新建文件(文件名随便),把需要的名称和类型放进去 &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt; &amp;lt;resources&amp;gt; &amp;lt;declare-styleable name=&quot;RefreshRecycleview&quot;&amp;gt; &amp;lt;attr name=&quot;isNeedLoadMore&
android自定义view能否给activity传值
笨笨的新人,第一次提问。rn最近在研究一些小游戏,游戏界面继承View类,我想把得分与进度条进行数据绑定。但是好像做不出来啊,于是就想进行传值。rn目前可以肯定:分数不能写成静态的,Activity的那一套传值方法View都不能用……rn新手,对Activity比较熟悉,而对View不够了解。
请教,如何在其它类中给CWinApp类发送消息?
可以用SendMessage吗?
如何在CMainFrame中给CChildView类发送消息
写了一个无模式对话框rn需要在CMainFrame中往CDlgDemo2View类发送消息以及设置CDlgDemo2View类的焦点,即SetFocus()rn由于CChildView是构造函数保护的,所以不能直接在CMainFrame类中声明CChildView m_wndView,然后m_wndView.SendMessage(……)这样吧rnrn我用的(CDlgDemo2View *)GetActiveView()->SendMessage() 不知道对不对啊 rnrn错误老是指向CDlgDemo2View.h文件中的rnpublic:rn CDlgDemo2Doc* GetDocument() const;rn显示 rn error C2143: 语法错误 : 缺少“;”(在“*”的前面)rn error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 intrn error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 intrn warning C4183: “GetDocument”: 缺少返回类型;假定为返回“int”的成员函数rnrn我用的是VS2005 MFC应用程序向导直接生成的 ~rnrn不知道为什么 高手解答~谢谢
请教,如何在Dll中给主应用程序发送消息
如题rn想在DLL中发送一个消息到调用它的界面程序中的窗口。不知道该如何解决。rnrn我现在是传了个 void* 的变量到DLL中,貌似不行。rnrn请教该怎么做。rnrn谢谢
如何在一个线程中给一个窗口发送消息?
如何在一个线程中给一个窗口发送消息?
Android -自定义view(三)自定义view的流程
自定义View的过程 1、先分析需要的自定义属性,编写,在构造函数中获取 2、重写测量方法,onMeasure(),决定View占据的空间大小 3、绘制View(Draw)自定义ViewGroup的过程 1、onMeasure测量自己及其子View的大小 2、onLayout布局,决定子View的显示 3、手势和用户的交互 onTouchEvent onIntercept
Android 自定义View——自定义View控件
Android给我们提供了大量的View控件,但这还是远远满足不了我们的要求,有时候开发所需要的控件形式是在Android提供的控件中是不存在,这就需要我们自己去定义一个。那么如何自定义控件?   学习自定义控件,首先要先掌握Canvas类的使用。   Canvas  Canvas, 我们称之为“画布“,主要适用于绘制View的。 Canvas中提供了大量绘制图形的方法:绘制扇形: drawA
相关热词 c# 线程顺序 c#昨天当前时间 c# 多进程 锁 c#mysql图片存取 c# ocx 委托事件 c# 读取类的属性和值 c# out 使用限制 c#获取url的id c#怎么进行分页查询 c# update 集合