powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / UrlEditor для подсвойства web контрола.
1 сообщений из 1, страница 1 из 1
UrlEditor для подсвойства web контрола.
    #32476233
andrejG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здесь собственно не вопрос, а предложение по решению проблемы.
М.б. кому нибудь пригодится.
Изучая построение собственных web контролов, я столкнулся со следующей проблемой.
Если своему контролу я добавляю некий атрибут, допустим Url, и назначаю ему редактор UrlEditor, то в инспекторе свойств в IDE при выборе этого свойства показывается кнопка с многоточием и открывается диалог выбора ссылки, т.е. все ОК.
Вот код этого контрола.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
 /*Файл Control1.cs*/ 
using System;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace MyWebControls
{
  [DefaultProperty( "Text" ), ToolboxData( "<{0 }:Control1 runat=server></{ 0 }:Control1>")]
  public class Control1 : System.Web.UI.WebControls.WebControl
  {
    public Control1():base( "a" ){}
    private string _text, _url;
    
#region Properties
    [Bindable(true), Category( "Appearance" ), DefaultValue( "")] 
    public string Text{
      get{return (_text==null)?string.Empty:_text;}
      set{_text = value;}
    }
    [Bindable(true), Category(" Appearance "), DefaultValue(" "),
    Editor(typeof(UrlEditor), typeof(UITypeEditor))] 
    public string Url{
      get{return (_url == null)?string.Empty:_url;}
      set{_url = value;}
    }
#endregion Properties
    
#region Override  
    protected override void AddAttributesToRender(HtmlTextWriter w)
    {
      w.AddAttribute(HtmlTextWriterAttribute.Href, Page.ResolveUrl(Url));
      base.AddAttributesToRender (w);
    }
    protected override void RenderContents(HtmlTextWriter w){
      w.Write(Text);
    }
#endregion Override  
  }
}

Если же атрибут это комплексное свойство, т.е некий класс на свойство котрого я навешиваю UrlEditor, то при просмотре в инспектроре свойств, так же появляется кнопочка с многоточием, но при щелчке на нее получаю ошибку "Object reference not set to an instance of an object.".

Ниже код этого контрола и класса реализущего комплексное свойство.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
 /*Файл Control2.cs.*/ 
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace MyWebControls
{
  [DefaultProperty( "Hyperlink" ), 
    ToolboxData( "<{0 }:Control2 runat=server></{ 0 }:Control2>")]
  public class Control2 : System.Web.UI.WebControls.WebControl
  {
    private HLink _hlink;

    public Control2():base( "a" ){}

#region Properties
    [Category( "Appearance" ), 
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    PersistenceMode(PersistenceMode.InnerProperty) /*,
    NotifyParentProperty(true)*/ ]
    public HLink HyperLink
    {
      get{
        if(_hlink == null)
          _hlink = new HLink();
        return _hlink;
    }
      set{_hlink = value;}
    }
#endregion Properties
    
#region Override  
    protected override void AddAttributesToRender(HtmlTextWriter w){
      w.AddAttribute(HtmlTextWriterAttribute.Href, Page.ResolveUrl(HyperLink.Url));
      base.AddAttributesToRender (w);
    }
    protected override void RenderContents(HtmlTextWriter w){
      w.Write(HyperLink.Text);
    }
#endregion Override  
  }
}


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
 /*Файл HLink.cs*/ 
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI.Design;

namespace MyWebControls
{
  [TypeConverter(typeof(ExpandableObjectConverter))]
  public class HLink
  {
    private string _text, _url;   

#region Properties
    [NotifyParentProperty(true)] 
    public string Text{
      get{return (_text==null)?string.Empty:_text;}
      set{_text = value;}
    }
    [NotifyParentProperty(true),
    Editor(typeof(UrlEditor), typeof(UITypeEditor))] 
    public string Url{
      get{return (_url == null)?string.Empty:_url;}
      set{_url = value;}
    }
#endregion Properties

#region Override
    public override string ToString(){
      return Text +  ";"  + Url;
    }
#endregion Override
  }
}

В результате долгих разбирательств, поиска в интернете, просмотра под дебаггером, штудирования документации я обнаружил, что UrlEditor в методе EditValue вызывает статический метод класса UrlBuilder.BuildUrl один из параметров которого д.б. IComponent, т.е. если я хочу что бы мое свойство корректно обрабатывалось, класс в котором оно объявлено должен реализовать интерфейс IComponent, или наследоваться от Control. Я попробовал и результат мне не понравился.

Задача подсунуть UrlBuilder-у не класс свойства, а Control в котором это свойство определено.
Вот что у меня получилось.
Объявляю интерфейс
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 /*Файл IControlChild.cs*/ 
using System;
using System.ComponentModel;

internal interface IControlChild
{
  IComponent ParentControl{get;}
}

Мой класс HLink2 реализует его, я так же добавил конструктор принимающий параметр типа IComponent.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
 /*Файл HLink2.cs*/ 
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI.Design;


namespace MyWebControls
{
  [TypeConverter(typeof(ExpandableObjectConverter))]
  public class HLink2 : IControlChild
  {
    private string _text, _url;
    private IComponent _parent;

#region Constructor
    public HLink2():this(null){}
    public HLink2(IComponent parent){
      _parent = parent;
    }
#endregion Constructor

#region Properties
    [NotifyParentProperty(true)] 
    public string Text{
      get{return (_text==null)?string.Empty:_text;}
      set{_text = value;}
    }
    [NotifyParentProperty(true),
    Editor(typeof(ExtUrlEditor), typeof(UITypeEditor))] 
    public string Url{
      get{return (_url == null)?string.Empty:_url;}
      set{_url = value;}
    }
#endregion Properties

#region Override
    public override string ToString(){
      return Text +  ";"  + Url;
    }
#endregion Override

#region IControlChild Members
    IComponent IControlChild.ParentControl{
      get{
        return _parent;
      }
    }
#endregion
  }
}

Класс Control3 использующий HLink2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace MyWebControls
{
  [DefaultProperty( "Hyperlink" ), 
    ToolboxData( "<{0 }:Control3 runat=server></{ 0 }:Control3>")]
  public class Control3 : System.Web.UI.WebControls.WebControl
  {
    private HLink2 _hlink;

    public Control3():base( "a" ){}

#region Properties
    [Category( "Appearance" ), 
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
    PersistenceMode(PersistenceMode.InnerProperty) /*,
    NotifyParentProperty(true)*/ ]
    public HLink2 HyperLink
    {
      get{
        if(_hlink == null)
          _hlink = new HLink2(this);
        return _hlink;
    }
      set{_hlink = value;}
    }
#endregion Properties
    
#region Override  
    protected override void AddAttributesToRender(HtmlTextWriter w){
      w.AddAttribute(HtmlTextWriterAttribute.Href, Page.ResolveUrl(HyperLink.Url));
      base.AddAttributesToRender (w);
    }
    protected override void RenderContents(HtmlTextWriter w){
      w.Write(HyperLink.Text);
    }
#endregion Override  
  }
}

И наконец мой расширенный ExtUrlEditor. Я его наследую от UrlEditor-а и переопределяю метод GetValue.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
 /*Файл ExtUrlEditor.cs*/ 
using System;
using System.ComponentModel;
using System.Web.UI.Design;
using System.Windows.Forms.Design;


namespace MyWebControls
{
  public class ExtUrlEditor: UrlEditor
  {
    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value){
      IWindowsFormsEditorService editorService;
      string result;
      IComponent component;
      object[] components;

      if (provider != null){
        editorService = (IWindowsFormsEditorService) provider.GetService(typeof(IWindowsFormsEditorService));
        if (editorService != null){
          result = (String) value;
          component = null;
          if (context.Instance as IComponent != null)
            component = (IComponent) context.Instance;
          else if (context.Instance as object[] != null){
            components = (object[]) context.Instance;
            if (components[ 0 ] as IComponent != null){
              component = (IComponent) components[ 0 ];
            }
          }
           /* вот сюда я добавил свой код все остальное выше и ниже код Microsoft */ 
          else if(context.Instance is IControlChild){
            component = ((IControlChild)context.Instance).ParentControl;
          }
          result = UrlBuilder.BuildUrl(component, null, result, this.Caption, this.Filter, this.Options);
          if (result != null)
            value = result;
        }
      }
      return value;
    }
  }
}


Теперь UrlEditor вызывается и для подсвойства комплексного атрибута.

P.S. Когда это решение уже сделал, обнаружил, что в библиотеке IE WebControls сделано похоже см. ObjectUrlEditor.cs, и даже гибче.
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / UrlEditor для подсвойства web контрола.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]