为什么我不能在声明一个WebForm一个用户控件的子元素(属性)? [英] Why can't I declare sub-elements (properties) of a UserControl in a WebForm?

查看:135
本文介绍了为什么我不能在声明一个WebForm一个用户控件的子元素(属性)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个班,这将使用这三类用户的控制。
下面是类及其说明:

  //可以访问多个ManagementMethods
[序列化(),ParseChildren(真)
公共类ManagementDelegate
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     PersistenceMode(PersistenceMode.InnerProperty)
     公开名单< ManagementMethod>方法
     {
         得到;组;
     }
}
//可以访问多个ManagementParameters和方法名
[序列化(),PersistChildren(假)]
公共类ManagementMethod
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     公共字符串名称
     {
         得到;组;
     }
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     PersistenceMode(PersistenceMode.InnerProperty)
     公开名单< ManagementParameter>参数
     {
         得到;组;
     }
}
//描述方法的参数。
[序列化(),PersistChildren(假)]
公共类ManagementParameter
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     公共字符串参数名称
     {
         得到;组;
     }
}
// ===============================
//这里是用户控制code中的一部分,背后使用ManagementDelegate类。
[可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
PersistenceMode(PersistenceMode.InnerProperty)
公共ManagementDelegate SelectMethods
{
    得到;组;
}
 

因此​​,这里就是我要寻找的结构的例子:

 < UC:MyUc ID =测试=服务器>
    < SelectMethods>
        <  - !在这里,当我打开一个标签asp.net中列出的方法,但是当我尝试设置名称属性也警告说,将不会运行。 - >
        <方法名称=甲基>
            <参数参数名称=ID/>
            <参数参数名称=字/>
        < /法
        <方法名称=meth2>
        < /法
    < / SelectMethods>
< / UC:MyUc>
 

问题是,ASP.net承认SelectMethod作为一个内部标记,甚至识别方法标记为内层标签,但它并不能识别标签的方法,实际上是ManagementMethod的类型。当我改变任何属性的类型简单的类型,例如更改列表只是ManagementMethod,ASP.net识别它,一切工作正常。你也一样有任何名单,LT;>对象

解决方案

下面是我们的生产code片段,您可以看到 ControlDependency 类甚至允许 ControlDependency

儿童

  [PersistChildren(假),类型转换器(typeof运算(ExpandableObjectConverter)),ParseChildren(真),序列化()]
    公共类ControlDependencySetting
    {
        [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content),
            PersistenceMode(PersistenceMode.InnerProperty)
        公开名单< ControlDependency> ControlDependencies {获得;组; }

        发射*** code
    }

[PersistChildren(假),类型转换器(typeof运算(ExpandableObjectConverter)),ParseChildren(真),序列化()]
    公共类ControlDependency
    {
        [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content),
            PersistenceMode(PersistenceMode.InnerProperty)
        公开名单< ControlDependency> ControlDependencies {获得;组; }

       ** code所发出

    }
 

而在自定义控件声明为

<$p$p><$c$c>[System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content),     PersistenceMode(PersistenceMode.InnerProperty)     NotifyParentProperty(真)     公开名单&LT; ControlDependencySetting&GT; ControlDependencySettings {获得;组; }

另外请注意,我做的每一个构造函数创建这些列表的一个实例。

的*编辑***

您已经叫你的名单方法和你的元素方法,你期望的子元素 ManagementDelegate 来自动添加到名为方法名单,这不是它的工作原理,当你想添加到您需要的列表指定列表元素,并添加在它的内部,你也做了相同的参数。

这是当前的结构会被期待的。

 &LT; SelectMethods&GT;
  &其中;方法&gt; &LT;  - 现在,这是方法的列表中,你也把它称为方法
      &lt;方法名称=甲基&GT; &所述;  - 这是要添加到你呼叫的方法列表中的方法类型的元素
            &LT;参数&GT; &LT;  - 这是参数列表,你可以把它叫做参数
                &LT;参数参数名称=ID/&GT; &LT;  - 参数元素
                &LT;参数参数名称=字/&GT;
            &LT;参数&GT;
      &所述; /方法&gt;
  &所述; /方法&gt;
 

您应该重命名为方法参数,并使用相应的或重新构造你的布局。

类似于

  //可以访问多个ManagementMethods
[序列化(),ParseChildren(真)
公共类ManagementDelegate
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     PersistenceMode(PersistenceMode.InnerProperty)
     公开名单&LT; ManagementMethod&GT;方法
     {
         得到;组;
     }
}

//可以访问多个ManagementParameters和方法名
[序列化(),PersistChildren(假),类型转换器(typeof运算(ExpandableObjectConverter))]
公共类ManagementMethod
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     公共字符串名称
     {
         得到;组;
     }
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     PersistenceMode(PersistenceMode.InnerProperty)
     公开名单&LT; ManagementParameter&GT;参数
     {
         得到;组;
     }
}
//描述方法的参数。
[序列化(),PersistChildren(假),类型转换器(typeof运算(ExpandableObjectConverter))]
公共类ManagementParameter
{
     [可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
     公共字符串参数名称
     {
         得到;组;
     }
}
// ===============================
//这里是用户控制code中的一部分,背后使用ManagementDelegate类。
[可浏览(真),EditorBrowsable(EditorBrowsableState.Always)
PersistenceMode(PersistenceMode.InnerProperty)
公共ManagementDelegate SelectDelegate
{
    得到;组;
}
 

然后

 &LT; UC:MyUc ID =测试=服务器&GT;
    &LT; SelectDelegate&GT;
       &lt;方法&GT;
          &lt;方法名称=甲基&GT;
            &LT;参数&GT;
                &LT;参数参数名称=ID/&GT;
                &LT;参数参数名称=字/&GT;
            &LT;参数&GT;
          &所述; /方法&gt;
          &lt;方法名称=meth2&GT;
          &所述; /方法&gt;
        &LT; /方法&gt;
    &LT; / SelectDelegate&GT;
&LT; / UC:MyUc&GT;
 

我相信这也可能离开指定肠子内容属于默认情况下,一个特定的属性,看的 PersistenceMode.InnerDefaultProperty - 。但我从来没有试过这种

I have three classes and a user control that will use these three classes.
Here are the classes and their explanations:

//provides access to multiple ManagementMethods
[Serializable(), ParseChildren(true)]
public class ManagementDelegate
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
     PersistenceMode(PersistenceMode.InnerProperty)]
     public List<ManagementMethod> Method
     {
         get; set;
     }
}
//provides access to multiple ManagementParameters and the method name
[Serializable(), PersistChildren(false)]
public class ManagementMethod
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
     public string Name
     {
         get; set;
     }
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
     PersistenceMode(PersistenceMode.InnerProperty)]
     public List<ManagementParameter> Parameter
     {
         get; set;
     }
}
//describes a parameter of method.
[Serializable(), PersistChildren(false)]
public class ManagementParameter
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
     public string ParameterName
     {
         get; set;
     }
}
//===============================
//here is the part of user control code behind that uses the ManagementDelegate class.
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
PersistenceMode(PersistenceMode.InnerProperty)]
public ManagementDelegate SelectMethods
{
    get; set;
}

So here is an example of the structure that I'm looking for:

<UC:MyUc ID="test" runat="server">
    <SelectMethods>
        <!-- here when i open a tag asp.net lists the Method, but when i try to set the Name attribute it warns and won't run. -->
        <Method Name="meth">
            <Parameter ParameterName="id" />
            <Parameter ParameterName="word" />
        </Method
        <Method Name="meth2">
        </Method
    </SelectMethods>
</UC:MyUc>

The problem is that ASP.net recognizes the SelectMethod as an inner tag, it even recognizes the Method tag as an inner tag but it doesn't recognize the type of Method tag which actually is ManagementMethod. When I change the type of any of the properties to a simple type, for example change the List to just ManagementMethod, ASP.net recognizes it and everything works fine. Thee same goes with any List<> object.

解决方案

Here is a snippet from our production code, you can see that the ControlDependency class even allows children of ControlDependency

[PersistChildren(false), TypeConverter(typeof(ExpandableObjectConverter)), ParseChildren(true), Serializable()]
    public class ControlDependencySetting
    {
        [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content),
            PersistenceMode(PersistenceMode.InnerProperty)]
        public List<ControlDependency> ControlDependencies { get; set; }

        ***Code emitted
    }

[PersistChildren(false), TypeConverter(typeof(ExpandableObjectConverter)), ParseChildren(true),Serializable()]
    public class ControlDependency
    {
        [System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content), 
            PersistenceMode(PersistenceMode.InnerProperty)]
        public List<ControlDependency> ControlDependencies { get; set; }

       **Code Emitted

    }

And is declared in the custom control as

[System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Content),
    PersistenceMode(PersistenceMode.InnerProperty),
    NotifyParentProperty(true)]
    public List<ControlDependencySetting> ControlDependencySettings { get; set; }

Also note that i do create an instance of these lists in each constructor.

*EDIT***

You have called your list Method and your element Method , you are expecting child elements of ManagementDelegate to be automatically added to the list called Method, this is not how it works, when you want to add to the list you need to specify the list element and add inside of it , you have done the same for parameters.

This is what your current structure would be expecting.

<SelectMethods> 
  <Method> <--Now this is the list of methods, you have also called it method        
      <Method Name="meth"> <-- This is an element of the method type to add to the list you have called Method
            <Parameter> <-- This is the list of parameters you have called it Parameter
                <Parameter ParameterName="id" />   <--parameter element             
                <Parameter ParameterName="word" />                
            <Parameter>
      </Method>
  </Method>

You should rename to Methods and Parameters and use accordingly or re-structure your layout.

Something like

    //provides access to multiple ManagementMethods
[Serializable(), ParseChildren(true)]
public class ManagementDelegate
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
     PersistenceMode(PersistenceMode.InnerProperty)]
     public List<ManagementMethod> Methods
     {
         get; set;
     }
}

//provides access to multiple ManagementParameters and the method name
[Serializable(), PersistChildren(false),TypeConverter(typeof(ExpandableObjectConverter))]
public class ManagementMethod
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
     public string Name
     {
         get; set;
     }
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
     PersistenceMode(PersistenceMode.InnerProperty)]
     public List<ManagementParameter> Parameters
     {
         get; set;
     }
}
//describes a parameter of method.
[Serializable(), PersistChildren(false),TypeConverter(typeof(ExpandableObjectConverter))]
public class ManagementParameter
{
     [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
     public string ParameterName
     {
         get; set;
     }
}
//===============================
//here is the part of user control code behind that uses the ManagementDelegate class.
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always),
PersistenceMode(PersistenceMode.InnerProperty)]
public ManagementDelegate SelectDelegate
{
    get; set;
}

Then

<UC:MyUc ID="test" runat="server">
    <SelectDelegate>
       <Methods>
          <Method Name="meth">
            <Parameters>
                <Parameter ParameterName="id" />
                <Parameter ParameterName="word" />
            <Parameters>
          </Method>
          <Method Name="meth2">
          </Method>
        </Methods>
    </SelectDelegate>
</UC:MyUc>

I believe there may also be away to specify that innner content belongs to a specific property by default, see PersistenceMode.InnerDefaultProperty - but i have never tried this.

这篇关于为什么我不能在声明一个WebForm一个用户控件的子元素(属性)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆