解决XAML自定义控件无法通过名称访问的问题

 
   | |

导读:本文介绍了如何解决WPF/Silverlight陷阱:XAML自定义控件的嵌套内容无法通过名称访问的问题并给出了详细的操作过程。

关键词:WPF Silverlight XAML自定义控件

 
正在加载数据...

    为了解决WPF/Silverlight陷阱:XAML自定义控件的嵌套内容无法通过名称访问的问题,我们首先要了解XAML自定义控件的实现原理,然后是控件的创建过程。希望本文能对大家有所帮助。

  为了说明这个问题,假定我们需要实现一个具有特殊功能的按钮控件。编写Xaml文件如下:

以下是引用片段:
<Button x:Class="TestWpf.XamlButton" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> </Button>

  对 Code Behind类,唯一的改动是把向导生成的基类从UserControl改成Button:

以下是引用片段:

public partial class XamlButton : Button  {
      public XamlButton()      
{
          InitializeComponent(); 
     }
  } 

  然后在主窗体中放上这个新创建的控件:

以下是引用片段:
<Window x:Class="TestWpf.Window1"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestWpf"
     Title="Window1" Height="300" Width="300">
     <StackPanel>
         <local:XamlButton x:Name="xamlBtn" Click="xamlBtn_Click"> 
            <TextBlock x:Name="xamlText" Text="Xaml Button" /> 
        </local:XamlButton>
     </StackPanel>
 </Window>

  看起来很平常的代码,但是很遗憾,编译无法通过。Visual Studio会告诉我们这样的信息:

  无法在元素“TextBlock”上设置 Name 属性值“xamlText”。“TextBlock”位于元素“XamlButton”的范围之内,该元素已经具有在其他范围中定义时注册的名称。

  或许是翻译的问题,这段错误提示可以说是文不对题,因为我们可以肯定的说:这个程序里面再没有别的地方用到xamlBtn或者xamlText这样的名称。

  如果我们换个方式,不再用XAML声明控件,而是用C#代码定义:

以下是引用片段:
public class CsButton : Button  {  } 

  然后再试试用同样的方式把这个控件加到主界面上:
  

以下是引用片段:
<local:CsButton x:Name="csBtn" Click="csBtn_Click">
     <TextBlock x:Name="csText" Text="Cs Button" />
 </local:CsButton> 

  完全没有问题!csText通过代码也是可以访问的,Click处理方法可以证明这一点:

以下是引用片段:
private void csBtn_Click(object sender, RoutedEventArgs e)  {
      MessageBox.Show(csText.Text);
  }

  如果用Silverlight来实验同样的代码,结果会稍有不同。在Silverlight XAML中添加x:Name并不会报错 ,但是运行时就会出现问题——xamlText总是等于null,并且FindName("xamlText")同样返回null,因此文本内容用自动生成的代码是无法访问的。但是以Button作为根对象来查找文本框,却能够找到:

以下是引用片段:
xamlText = (TextBlock)xamlBtn.Content;
  HtmlPage.Window.Alert(xamlText.Text); 

  此实验可以说明:用XAML来声明自定义控件是存在严重问题的,控件内容中的对象无论是通过自动生成的成员变量还是用根容器的FindName都无法访问。要绕开这个限制,有以下几种可能的途径:

  1. 使用C#手工构造自定义控件,不用XAML声明;

  2. 使用自定义控件的FindName找到内容对象,然后手工绑定到成员变量;

  3. 使用RegisterName手工管理命名空间。此方法我没有实验,并且它仅对WPF有效,Silverlight是没有这个方法的。

  上述方法2是我们最初曾经使用的方法,但是目前已经放弃了,因为手工绑定需要程序员自己编写大量无聊的代码,并且非常容易出错。方法1是目前采用的方法,为此我们删除了许多原先已经写好的XAML,全部改用C#代码手工创建,其实这个工作并不算困难,因为大多数时候XAML到C#的映射还是比较直观的,但由于Silverlight的自身设计的限制,存在一个明显的限制:

  不像WPF,Silverlight里面没有简单的办法可以从代码创建一个Template。在WPF中,可以指定Template.VisualTree,但是Silverlight没有提供这个属性,所以要从代码里是生成Template是很困难的。网上曾有人提供过一个思路,即用字符串拼出模板的XAML字符串,再用XamlReader.Load读出模板对象。这个方法虽然可行,但比较丑陋,拼字符串总是下下策,维护也很困难。我们现在使用的是一个折中的办法,Template还是用XAML来保存,但是需要编写一些自定义代码,以便把C#控件和XAML中的模板关联起来。不幸的是,这个办法导致本来是同一个控件的内容不得不在两个地方分别维护,还要时时注意两边的代码保持同步,因此也不能说是一个完满的解决办法。

  后记: 我现在主要的工作,是基于Silverlight开发一个应用程序平台,在此过程中已经感觉到Silverlight的一些不足,包括实现上不够完整(比如说缺少Decorator,没有OnRender),部分API在版本之间的大幅度变动(针对Silverlight 3 Beta的一些例子现在都已经失效了),也有设计上的复杂性导致的一些微妙的问题,本文所提到的就是这些问题的其中之一,给框架层面的实现带来了不少麻烦。此外值得一提的是,我们现在编译的xap包大小已经长到了800k以上,可以说和Adobe Flex编译出来的文件大小不相上下。对于文件大小“贡献”最多的是System.Windows.Controls、System.Windows.Controls.Data、System.Windows.Controls.Toolkit和System.Xml.Serialization这四个程序集,其中除了最后一个或许可以考虑以后不再用XML序列化,前面3个是不可能不使用的。所以Flex文件编译以后6、7百K的体积真的算不上大,Silverlight同样是这个水平,那些总是叫唤文件太大的同学也应该了解,RIA程序的尺寸基本上也就这样了,除了用RSL之类技术切割一下以外,已经没有多大优化的余地了。如果这个大小您也不能接受的话,那还是用回Ajax吧。

原文出处:http://developer.51cto.com/art/200910/159766.htm
 
来源:51cto    作者:Shuhari     
 
 
 
 
 

数据治理与管理

 
随着越来越多的以主数据管理问题解决为主要内容的SOA应用集成的创建,数据方面的专家Informatica加强了其用SOA特征处理的平台。
 
企业mashup把分离源的数据和服务连接到新的应用中。由于它们可以被容易的与其他类型的软件比较,还因为它们能够脱离现有系统创建新的功能……
 
在Gartner的企业架构的最高会议上,EA以及移动软件厂商Sybase在PowerDesigner产品从企业建模到IT规划宣布合作伙伴关系。
 
无用信息输入、无用信息输出作为应用程序开发者和SOA倡导者再次使用主数据管理(MDM)的颂歌,以确保其复杂的综合系统是工作在正确的信息上。
 
为数据建设一致的架构正是MDM所做的事情。SOA涉及后便意味着建设一种一致的方法作为服务来封装和传递数据。观察表明,一些采取了MDM的SOA……

热门技术手册排行

 

随着开源技术越来越成熟,一个稍有开发经验的人通过学习就可以用开源的产品和技术构建一套可用的系统。对于从事软件开发的人员,尤其是对Java或动态语言相关领域的人来说,“开源”也许是他们最喜爱的单词。但是,很多时候我们需要的不仅仅是一个可用的系统,而是希望这个系统开发更简易、性能更高和扩展性更好等。这确实是一个令人头痛的问题。本指南很多地方都是点到为止,要深入了解相关信息的读者请借助参考资料、网站等自行挖掘。

 

本专题分六部分探讨SOA设计模式,当初设计面向服务架构的一大初衷就是降低服务间耦合度,由此提高服务的灵活性和自由度。

 

业务流程管理(business process management,bpm)不是一个新概念,甚至不是一个新名词。它是从相关的业务流程变革领域,如业务流程改进(bpi)、业务流程重组(bpr)、业务流程革新中发展起来的。流程管理技术也是从早期的工作流管理、eai、流程自动化、流程集成、流程建模、流程优化等技术中发展起来的。

 

TOAGF是一个架构框架,简而言之,TOGAF是一种协助发展,验收,运行,使用,和维护架构的工具。它是基于一个迭代(Iterative)的过程模型,支持最佳实践和一套可重用的现有架构资产。

 

云计算的概念越来越流行,Amazon、Google和IBM是第一批将云计算引入公众视线的公司。云计算就是新的Web2.0,一种既有技术上的市场绽放。

 

Mashup是一个非常cool的新的应用程序种类。如果你想真正的了解它们,我们需要回过头来看看你现在的计算机,其实它就是一个非常好的帮助你理解mashup的模型。现在开源的操作系统无疑是非常好的apis的集合或应用程序编程接口,帮助开发者去构建其应用程序。计算机本身也是一个很好的为用户提供接口的例子,键盘和鼠标可以被理解为你通过计算机的接口而使用的不同的应用程序。本技术手册为读者提供了一些相关信息,如果需要深入了解mashup,读者可以借助其他参考资源。

查看更多
 
 

登录TechTarget中国

关闭
本服务仅向TechTarget中国的会员开放,请登录或立即免费注册
电子邮件地址:
请输入您的电子邮件地址
密码:
下次自动登录