在WPF中自定义控件_第1页
在WPF中自定义控件_第2页
在WPF中自定义控件_第3页
在WPF中自定义控件_第4页
在WPF中自定义控件_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在wpf中自定义控件(1):概述周银辉一,不一定需要自定义控件在使用wpf以前,动縄便用自定义控件几乎成了惯性恩维,比如需耍一个带图片的按钮,但在wpf中此类任务却不幣耍如此大费周章,因为控件可以嵌 套便川以及可以为控件外观打造一套新的样式就可以了足否需耍我们来fl定义控件,这需耍你考虑目前己有控件的戊止逻轲功能而不翌局限丁外观,如果 目询的控件都不能直觉地表达你的想法,那么你可以1*1己來打造一个控件,否则,也许我们仅仅改变一下目前控件的膜板鏗就可以完成任务很女人在"定 义控件上经常犯的错谋是:碇父撰写己有的逻徘二,u$erotrol 还是 cutomcontrol?耍庄xvpf中

2、门定义一个控件,便用u&ercontrol与customcontrol都是不错的选择(除此z外,还冇更篡选择,比如打造一个fl定义的面板,但这不在本文 的讨论范国)他们的区别在丁:usercontrolh-更像winfonn'i-n定义控件的开发凤格,在开发上更简单快速,几卩可以简单地理解为:利用设计器來将多个c右控件作为子元索來拼凑 成_个usercontrol并修改其外观,然后后台逻辑代码直接访何这些子元素贞堆大的弊端在于贞对模板样式導支持度不好,其重复便用的范围有限.customcontrol, h开发出來的控件才戊止具冇vpf凤格,其对模板样式仃看很好的支持,这足冈为打

3、造customcontrol时做到了逻辑代码与外观相分离, 即便换上一套完全不同的視觉树其同样能很好的i.作,就像vpf内超的控件一样.在使用visual studio打造控件时,usercontrol与customcontrol的差别就更加明显,在项11屮添加一个usercontrol时,我们会发现 设计器为我们添加了 个xaml文件以及一个对应的.cs文件(或.vb零),然后你就可以像设计普通謝体一样设计该usercontrol;如果我们是在项目中添加一个customcontrol, 情况却不是这样,设计器会为我们生成 个.cs文件(或.vb等),该文件用丁編写控件的后台逻 辑,而控件的外

4、观却定义在了软件的应用主题gme)中了(如 果你没有为软件定义通用主起次会1*1动生成一个通用主題themes'genenc xaml.然后主題中会1*1动为你的控件生成一个style),并将通用主題与该控件关 联了起來这也就足customcontrol对样式的支持度比usercontrol好的廉冈.三,继承于uhicobtorucontrd还是其它?如果你准备打造 个控件併便用像visual studio这样的i.具來开发的话,打造useicontro 1时其会1'1动为你从system.windows.controls.usercontrol继 承,打造customcont

5、rol时英会为从system.windows.controls.control继承.但实际惜况下,也许我们从他们的衍生类别开始继承会得到更女的好处(更好的吭 用己仃的逻辑),比如你的控件拥冇更篡的类似v button的某叫恃性,那么从button开始继承就比从control继承少写很多代昭.在接卜-來的儿节中,我们会逐步讨论如何打造usercontrol与cxistomcontrol以及让它们更好支持wpf和待性.在wpf中自定义控件(2) usercontrol周银辉在这屮:我们将将打造 个usercontrol(用户控件)來逐步讲解如何在vpf '|' |'|定义控

6、件,并将wpf的一些新持性引入到|'|定义控件中來.我们制作了一个带语音报时功能的钟衣控件,效果如下:cbckde1 s:c4:23在vs中右键单击你的项ii,点击”添加新项日",在出现的选择列衣中选择"usercontrol".vs会fl动为你生成一个*.xaml文件以及英对应的后台代码文件 g或我它).的是,"动生成的代码中,你的控件足继承于system.windows.controls.usercontrcl类的,这对应你的控件而言并不一定足录恰当的基 类,你可以修改它,但注总你应该同时修改*.cs文件和*.xaml文件中的基类,而不只是修

7、改tcs文件,否則当生成项目时会报错"不是继承丁同一基类".修改 8xain 1文件的方法是:将该文件的第一行和录品行"usercontrol"改成打你认为恰当的基类名称.1,为控件添加属性(依聯11性,dependencyproperty)止如下面的代码所示:public scacic readonly dependencyproperty timepropery =zependencyproperry. -egiser ("tiir.e1', zypeof (datetime) z zypeof (clockusercrrl),ne

8、w frair.eworkpropertyketadata (dacetime .no讨,nexi; propertychangedcallback (timepropertychangedcallback) >我们为控件(或打任何一个wpf类)添加的依聯屈性都是"公开的”,"静态的”,"只读的",英命名方式足”屈性名+proper匸y”,这是依赖属性一成不变的 节写方式.对丁依赖屈性的注册可以在曲明该属性时就调用dependencyproperty.register ()方法注删,也可以在其静态构造方法中注册.上面的 dependency?rcp

9、er-y.register方法的几个参数分別是:屈性名(该屈性名9注明的依赖属性名称"xxxproperty"相比仅仅是少了"property" 后缀,其它完全一样,否則在运行时会报异常),尿性的数携类型,届性的拥有者的类型,元数据.关j'参数屮传递的元数抵:如果是普通的类则应该传递propertymetaaa-a,如果足framewcrkelement則可以传递 framewcrkpropertymetadaca,其中framewcrkpropertymetadaca屮可以制定此标记农明该屈性发住变化时控件应该做出什么反应,比如某 w性的变化会

10、彩响到该控件的绘制,那么就应该像这样m写该屈性的元数据:new framewcrkpropertymetadaca (defaulevalue, framewcrkpropertymetadacaopticns .af fectsrenaer);样"j该屈性发生变化时系统会考总匝绘该控件.刀外元数据中还保护很篡内容,比 如默认值,数据验证,数据变化时的回调函数,足否参与屈性”继承"鏗.然后,我们将该依赖加性包装成普通届性:description ("»取或设樂当前日期和时间j】category (''common propertles1*

11、)public dacetime timeeeget黑(recurn (dacetime)this.getvalue(timeproperty);卜 set黑(chis. setvalue (titneproperty, value);卜 l gecvalue和secvalue方法來i'l j: dependencyobject类,其用j:获収或设??类的某皿性值.»:在将依赖加性包装成普通屈性时,在get和sec块中除了按部就班的调用getvalue和servalue方法外,不要进行任何冀它的操作.下而的代码是不恰当的:(description取或设饪当前日期和时间t】ca

12、tegory (''common propertles1*) public dacetime timeeeget於(recurn (dacetime)this.getvalue(timeproperry); secchis. setvalue (titneproperty, value);chis.ontimeupdated(value);/error在以前这或许足很多人的惯用写法,但在wpf中,这样的写法在潜庄的错谋,廉肉如下:我们知道继/ft ? dependencyobject的类珈有getvalue和 secvalue方法來获取或设氏,尿性值,那为什么我们不氏接使用该方

13、法來谈取或设賢皿性值,而婴将兀包装成秤通的.net属性呢川实上在这里两种方 式都是可以的,只不过包装成普通 的.net属性更符合.net开发人员的习惯,便用ge匸value和setvalue更像java开发人员的习惯,但xaml在执 行时1uf t java开发人员一样,英不会调川.net加性而足fi接便用gecvalue或setvalue方法,这样一来,我们写在get块和sec块中的其它代 码根木不会被xaml执行到.所以说,就上面的time航性而言,c# (或英它)对该屈性的调用不会出现任何何題,但该属性被用在xaml中时(比如右:xaml 对该屈牲进行数据绑定術,h- set块中的thi

14、s. ontimeupdaced (value);语句不会被执行到.那么,当time屈性发生变化时的确需耍调川this. ontimeupdated(value);语旬(冈为该语句会引发时间被更新了的爭件),还足在传递的依赖屈性尤数据做文貳:new framework?rcperymecadata(datetime.now,new(timepropertychangedcallback),我们为属性的变化拆定了个阿调惭数,“1该屈件变化时该冋调用数就会被执疗:private scacic vod timepropertychangedcallback(dependencycbject send

15、er, dependencypropertychangedevencargs arg) eeif (sender != null && sender is clockuserccrl)黑(clockuserccrl clock = sender as clockuserctrl;clock.ontimeupdaced(dacetime)arg.01dvaluez (dacetime)arg.newvalue);&为控件添加事件(传阅事件砂irtedevent)添加传阅車件的方法与添加依赖屈性的方法很类似:public static readonly roiitedeve

16、nt timeupdatede'. eiit =et-entmanager.registerroutede,.-ent(',timeupdated,*,routm 岸 strategy .bubble, tpeofcroutedpropemhangede'.enthandlekdatetime. n,t>eof(clockuserctrl);集支持方法eventmanager. registerroutedevento对应的几个参数分别为:爭件名称,事件传阅的方式(向上传阅,向下传阅或不传阅),事件对应的eventhandler的类型,爭件拥冇齐的类切然后将車件包

17、装成普通的net爭件:descnption("li期或対间被史新后发牛.”)public e.-ent routedpropem<hange<ie,. enthajidler<datetime> timeupdatedeeadde申this. addhandleift lmeupdatede.-ent,十 alue);remo'i-ee申dus.remo'. ehaadleixtiineupdatede'.-ent, value);ii总,与依赖,尿性一样,不耍在add与remove块中添加除addhandler与removehandl

18、er以外的代码.题外话,事件参数中的e.handled=true并不是终止爭件的传阅,这只是为爭件做-个标记而己,以便在默认情况卜的让那些爭件处理函数在该标记为true的情 况卜-不被调用,要为该标记为true的“件注刪处理方法并让该方法得到执彳亍,请便用addhandler方法j:把脚订个参数bandlereventsto。设腔为tnie,如卜:this.mylnkcan'i-as.addhandlercinkc an-« -as .mouseleftbuttondonet-ent. new mousebiittone'.enthandleit myinkcant-

19、as_mouseleftbuttondoti).true);pri-ate 十 oid mylnkc anva$_mouseleftbvittondoxn( object sender. mousebiittone'. entargs e)/do something 然后編写惯川的onxxx方法:protected virtual void ontimeupdated(datetime oldxalue. datetmie neafalue)eeroutedpropert>,chadgedet-entarg$<datetime> arg =new routedprop

20、em<'liange<ie,. eiitargs<datetime>(oldyalue. ne-x alue,timeupdatedevent); this.raisee'i-enarg);3,为控件添加命令(commands)能为fl宦义控件添加如vpf内置控件一样的命令是 件很不错的khvcji实卜.这也是 customcontrol中降低界而和后台逻辑耦介度的种方汕.木系列随笔中的下一篇中将会兵体谈谈).vpf屮内世的命令仃两大类型:roiitedcommand以及routeduiconmxand.,'u者比前再多了 个text屈性丿i在界

21、面上|木地化 地显乐该命令对屁的文 8木,更多的町以参石wpf屮的命令与命今绑定()以及wpf屮的命令y命今绑定().这里我们來定义-个命令,其功能足控件的语w报时忤先我们定义一个命令:public static readonly roitteduicommand speakcommand = new roitteduicommandcspeak'. speak". t)peof(clockuseictrl);参数分別为命名的显示名称,命令的名称,命令的拥冇者类型然后在控件的静态函数中定义个命令绑定,该命令绑定定义了命令的具体細节:对.应的命令是什么?宾完成什么样的功能,当前

22、环境下其能执行吗?c ommandb mding commandbin<lmg =new commandbmding(speakcomniani new execiitedroutedetenthaudlei(e?cecutespeak), newcaiiexecuteroute<iet-enthandler(canexecutespeak);pnvatq static void execiitespeak(object sender. executedroutede'. entargs arg)eefclockuserctrl clock = sender as cloc

23、kuseictri;if (clock != null)韓clock. speakthetimeo; pnvatq static void canexecutespeak(object sender. canexecuteroutede*'-entargs arg)eefclockuserctrl clock = sender as clockuseictri;arg.caxiexecute = (clock != null);canexecuteroutedeventargs的canexecuce属性用掘示"i询命令是否可用,也就是说系统会不断地检視该命令打该命令的 作用对

24、彖,并根据你 所捉供的条件來判断当前命令是否可用,比如文本框状态变为"只读"后,刘粘贴”命令将不可用,作用丁该文本松的粘姑按钮会1*1动被禁用,反z则启用 new execucedrcutedevenchandler (executespeak)委托拆述了 "i该命令被执行时所婴完成的任务,这通过1“1调excutespeak两数來实现.pn-ate static void execiitespeak(object vender. executedroutede'. entargs arg)eefclockusexctrl clock = sender a

25、s clockuseictri;if (clock != null)e申clock. speakthetimeo;pn-ate 十oid speakthetimeoeefdatetime localtime = this.time.tolocaltimeo;string texttospeak = m现 在时刻localtime.toshortdatestringo +'*,*localtime. toshorttimestringo +,星期.+ (molocaltime.dayoweek:thi$.speecher.speakasync(texttospeak):l 我们也町以为命

26、令添加快捷键,这是通过inputbmding來实现的洪将命令9命令的快捷键关联起來,比妣inputbmding mputbinding = ne* inpiitbmding(speakcommani ne* mousegestiire(mouseaction.leftchck);commandmanagerregisteiclassinputbmdmgktypeokclockuseictrl), mputbindmg);这样严我们风标点击控件时就会引发控件的speak命令,从而调用speakthetime函数进行语音播报.快她键町以通过iousegesture或keygesture來定义.4,

27、优点与缺点:止如在九丸tf屮|'|疋义控件'i'谈到的一样,usercontrol陡比较快速的打造d定义控件,但其对模板样式鏗缺乏很好的支持,打造出來的控件不如wpf 内世控件 样灵活,右:木系列馳笔的下篇中,我们将介绍如何打造能对wpf新特性捉供完全支持的customcontroldemo在wpf中自定义控件(3) customcontrol (上)周银辉为快速地为你的血用定制一个零部件,你需婴的是useicontrol,这可以参考在wpf屮fl足义控件usercontrol,为了让你打造的控件更标准化,更灵 活以及更具右普逛总义,你尙耍用到的customcontro

28、l,这止足木文妥介紹的.1 踊建 castomcontrol在选择控件基类后,第一件車惜便足在你的项目中新建”customcontiol",我们会发现在项目中1*1动生成了一个匸cs(或* vb或冀他)文件以及 themesgeneric. xaml(如果原来没有的话),他们分别是 customcontrol的后台代码文件(code behind)与控件的默认主题文件,打开 themes'generic.xaml,你会发现k'l'fl动生成了一个style,这是你的控件的默认样式,止如vpf内就控件也右它的默认样式一样.这时,我们的i.作就被 分成了两个部分,

29、是在xxx.cs文件中编辑控件逻轲,而足在generic.xaml中编 写hui.2,gericaml中的styk是如何与我们的控件联系在一起的打开xxx.cs文件,你会发现静态构造方法中,vs门动地带你扱盖了控件的defhultstylekey(1*(:static customcontrol 10eedefaxiltstylekeypropertyoemdemetadata(typeof(cu$tomcontroll), new frainevorkpropert-metadata(typeof(customcontroll);我们知道defaultstylekeyproperty是fra

30、meworkelement以及fraineworkcontentelement癸用來 指示控件的默认if的屈性,该屈性仃个很持別的地方就是我们不能够用继水的思想來思考它,比如说button的默认样式泄伉是stylel.j畀类mybutton的默认样式键值是style2(或者没冇指定默认样式), 尽管mybutton可以向上转型成button类,但我们井不希望冀转型后的 默认样式键值为stylel.所以vpf采用了在子类控件的静态构造方法中碇写 defaxiltstylekey尤数据的方式來拆定该了类控件的默认样式.1:血代码中,我们将new frameworkpropertymecadata

31、(typeof (cusrcmcon-roll) 指定为其新的元数据值,这个值代表若,我们将在资源丫典中査找 个键值为n-peof(customcontroll)的style來做为控件的默认样式.而这个样式刚好被我 们定义在了 generic.xaml中:<style targettj-pe=m (x:type locahcustomcontroll"><setter property="template"><setter.valie><c ontroltemplate targett>pe=" x:typ

32、e local: customcontrol 1<border backgrouxid=" templatebmding background"borderbiusli=" temphtebindmg borderbrushmborderthickness=* temphtebinding borderthickness"><border><c ontroltemplate>setter. value</settei>u'style>这是大家可能冇个疑问,上面xaml中的style并没有指定k

33、ey值啊,而我们的控件耍求的默认样式key值为 卯eorcustomcontroll),并且资源7典 中的元索肯定足翌仃key的?这是style的基木钏识了,在wpf中,为style指定key时冇两种方式:一足明购指足key,而足在没冇明确指定key的惜况下 指定targettvpe.tf会1动地将其可key设:世为typeof(targettype).如果你仃在blend中为控件打造style的经脸的话,你会注童到新建一个style时bend 会捉供一个“apply to all"选项,这也是为什么你打造的style可以"apply to all"的奥秘所在.1

34、23, “gericqnr这个名称并非偶餓通过上面的叙述,你可能会有冲动将genenc xaml中的style代码咧切出来,粘貼到任何一个我们的控件可以找到的地方,然后把genenc.xaml删掉或改 成更优雅的名称,如果你运气好的话,这是可行的,因为控件会1'1下而:(page«app.theme)去金找英所需耍的style,但此时你(2经犯了一个潜在的错谋:你没冇 为控件捉供默认的样式这里的默认样式其实是说"在默认主題中或没仃为该控件找到艸前操作系统对应的主题时采用的的样式”这涉及到wpf屮theme 的相关话題了,右兴趣可以参考msdn相关sdk.4, 打造你

35、的控件逻辑这是必然的,添加届性,添加爭件,方法箋空这西你可以参考在wpf中门定义控件usercontrol,这里就不吭复叙述了一&打造控件ui这里值得一捉的是我卄常佩服在vs的xaml海洋也"裸泳"的兄弟们,不过我更推荐使用microsoft expression blend來完成这项艰巨的任务.另外,如果 你发现wpf内置控件在blend屮很好用而我们自己打造的控件却不是这样,那么请注意了,你的控件逻辑可能设计得不規范.绥件ui部分与逻辑部分的耦合度这足一个容易被忽略但却ii:常雨耍的何题,我们z所以使用customcontrol而不是usercontrol,足肉

36、为我们希望fl己的控件能向wpf内置控件一样, r-uifts轻易地被1(他川户定制或我们将來所改变.也就是说其視觉树不能与后台逻徘纠缠在一起,因为其视觉树中的元素完全可能被你的控件用户改变 比如,如果你的控件的视觉树中有一个buttonjiij你在该button的click m件中做了一此控件的逻辑处理,那么很町能你的控件打造失败了,因为该button可 能会在用户碗新定义控件template时被删除-在 wpf中自定义控件(3) customcontrol (下)在wpf中自定义控件(3) custoncontrol (下)周银辉1,控件ui部分与逻辑部分的耦合这是 个容易被忽略但却ii,

37、;,t侦的问题.我们z所以便丿1 customcontrol iij仁是usercontrol.是1人1为我们希刃自己的拧件能向wpf内代控fl iv.hui 能轻易地被其他用户定制或我们将來所改变也就足说其視觉树不能与后台逻辑纠编在一起,因为英视觉树中的元索完全可能被你的控件用户改变上匕如, 如果你的控件的视觉树中有 个button,而你在该button的click車件中做了 些控件的逻辑处理,那么很可能你的控件打造失败了,因为该button可能会 在用户碇新定义控件template时被删除-在讨论解决方案z前,需婴捉醒的是:一定耍注意控件的逻轲与ui衣现(style.template)备|

38、'|职击的区分.不属亍后台逻徘竇的車惜后台逻轲就 不婴管,不屈 于界面符的事情界面基本上也符不了或者说做起來很麻烦一个简单的例子足:1:匕如说你想iu标移动到你的控件上的爭惜,控件稍稍变大一点,ir标离开控 件时控件大小又还原(或其他比较绚丽的效果),那么你在控件上的后台逻辑屮添加的mouseenter与mouseleave爭件的处理来达到这效ju.这时你的后台 逻轲就管得过宽了,冈为这种效果是style的爭情,你可以把它肢在控件的默认style中(在generic.xaml中,你可以参考在wpf屮“定义控件 customcontrol (上)來捉供给控件用户而不屁该加在后台逻轲中而费

39、力不讨好.这不但噌加了辐合,而且在用户祈來这也冇些"强奸民意",因为他没冇办法通 过ii定义的style來披盖掉你认为比较漂亮的控件效果-虽然vpf将ui与后台逻轲的隔离c经做得很不错了,以便ui设计师陡和我们更好的沟通和分i.协助,但这并不盘味若.wpf可以将ui与后台完全的隔离 而4不影响.車实上,我们在編写品台逻辑的时候常常需婴用到控件ui树中的某些元索才能完成,比如在編"iprogressbar时我们需耍知道视觉树中的某个 农示"总竝"的元索的长度或高度,以便根据progressbar的当前value來确定视觉树屮另外一个衣示"

40、;当前城"的元索的长度或高度.还冇种怡况是,我们品 台写好了一个不错的逻抵但船耍视觉树中的某个ui元索來明渤调用,比如说,我们在scrollbar控件中写好了 linedowo方法,但该方法船耍用户点击控件 视觉树中某个表示”向下滚动一行"的元索(比如一个向下的箭头)时來调用.vpf 捉供了两种方案,一是利用 templatepartattribute,二足使用 command.1.1 templatepartattributetemplatepart适用p上面所说的第一种情况贞用丁吿知用户,在11前的惜况下必须在控件的视觉树中心在拆定类型和名称的元索才能是控件发挥完整的功

41、 能,否则可能&致功能丧失或需耍用户fl行处理讯除视觉树中的该元索而帯來的品遗症如果我们足某个控件的便用斤且其注明了该屈性,那么我们在修 改控件的template时就应该保证控件屮足拆存在其拆明的特定类型和名称的元索,除ikttwtld的确不需耍其关联的相关功能或你已另仃处理.在vpf内祝控件中,这种类型的控件很多,比如combobox.pass-ordbox,progressbar零零.我们 fit comboxbox:templatepartattribute(name = "part_editabletextbox", typw = t)peof(textbo

42、x)templatepartattribute(name = "part_popupm. type = typeo£(popup)locahzabihtyattnbute(localizationc ategorj-.c ombobox)st>-let)pedpropert)-attnbute(property = "itemcontainerstyle'. styletargett)pe = t>peof(comboboxitem)public class coxnbobox : selector我们发现兀仃两个templatepart .w

43、性,个是textbox类型的'tart.ednabbt敗box”,另一个是popup类型的p.artjopupjjij者用編辑文本亦打用弹 出列表项,如果某个用户在|'1址义该控件的template时缺少了这两个元索,将失去相应的功隠我们的控件也可以仿照combobox來规定必须的部件,并0vemde -些onapplytemplaeo方法來取得相应元索:public o-emde void onapplytemplateoeebase.onapplytemplateo;button mybtn = base.gettemplatechild(hpart-btnw);if (m

44、ybtn != null)韓mybtn.click -= new routedeventhandler(mybtn_cick):- 1j command这适合上面捉到的第二种情况,即是我们品台写好了 个不错的逻辑,但需践视觉树屮的某个ui元索來明确调川.比如scrollbar的i:端和卜-端的两个小箭 头用來上下翻行,我们明显不能在这两个小筋头的鼠标点击事件中调用lmedoxvn方法.那么止确的做法足,将后台逻轲中的linedown和lineup方法包装 成linedowcommand和lineupconmiand.然品将視觉树中的元索的command屈性绑定到相血的command匕这样來,即便用户修改视觉树屮的上下小 箭头为冀他类型的元索,用户也可以通过命令绑定來打相应的功能联系起來.比如'vpf内况的scroolbar控件的向下小箭头的xaml代码便足如卜h写的:<repeatbutton isenabled=" templatebinding ismouseo.-er" style=" staticresource scrollbarbutton * gnd ro-m2w command=" x: static sc

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论