Приведение с переменной, назначенной некоторого типа

То, что я пытаюсь сделать, это выполнить приведение, необходимое для добавления моих элементов управления в Ext.Net.Panel.

Это мой пример кода:

   Ext.Net.Panel panel = new Ext.Net.Panel();
   Control control = (Control) null;//here can be any Ext.Net type as well as NumeticField for example Ext.Net.TextArea and so on
  switch (infoAttribute.Type)
                                {
                                        case PropertyTypeAttrib.Text:
                                            control = (Control)new Ext.Net.TextField();
                                            ((TextField)control).FieldLabel = infoAttribute.HeadLine;
                                            control.ID = propertyHelper.Name;
                                            //panel.Items.Add((TextField)control);
                                        typeToCast = typeof (TextField);
                                        break;
                                    case PropertyTypeAttrib.FileUrl:
                                        control = (Control) new Ext.Net.HyperLink();
                                        control.ID = propertyHelper.Name;
                                        ((Ext.Net.Label) control).FieldLabel = infoAttribute.HeadLine;

                                        //panel.Items.Add((Ext.Net.HyperLink) control);
                                        typeToCast = typeof (Ext.Net.HyperLink);
                                        break;
                                    case PropertyTypeAttrib.Enum:
                                        control = (Control) new MMPControls.Web.ComboBoxEnumExt();
                                        ((MMPControls.Web.ComboBoxEnumExt) control).EnumerationTypeName =
                                            propertyHelper.PropertyType.Name;
                                        control.ID = propertyHelper.Name;
                                        ((MMPControls.Web.ComboBoxEnumExt) control).FieldLabel = infoAttribute.HeadLine;
                                        //panel.Items.Add((MMPControls.Web.ComboBoxEnumExt) control);
                                        typeToCast = typeof (MMPControls.Web.ComboBoxEnumExt);
                                        break;
                                    case PropertyTypeAttrib.Date:
                                        control = new MMPControls.Web.DateSelect();
                                        control.ID = propertyHelper.Name;
                                        //panel.Items.Add(
                                            //(MMPControls.Web.DateSelect) control);
                                        //panel.Items.Add((MMPControls.Web.DateSelect)control);
                                        typeToCast = typeof (MMPControls.Web.DateSelect);
                                        break;
                                    case PropertyTypeAttrib.DateTime:
                                        control = new MMPControls.Web.DateSelect();
                                        control.ID = propertyHelper.Name;
                                        //panel.Items.Add(
                                            //(MMPControls.Web.DateSelect)control);
                                        typeToCast = typeof (MMPControls.Web.DateSelect);
                                        break;
                                    case PropertyTypeAttrib.TextInteger:
                                        control = (Control)new Ext.Net.NumberField();
                                        ((NumberField)control).AllowDecimals = false;
                                        ((NumberField)control).MinValue = 0;
                                        ((Ext.Net.NumberField)control).FieldLabel = infoAttribute.HeadLine;
                                        control.ID = propertyHelper.Name;
                                        //panel.Items.Add(
                                            //(Ext.Net.NumberField) control);
                                        typeToCast = typeof (Ext.Net.NumberField);
                                        break;
                                    case PropertyTypeAttrib.IList:
                                        //TODO: 
                                        break;
                                    case PropertyTypeAttrib.ImageUrl:
                                        control = (Control)new Ext.Net.Image();
                                        control.ID = propertyHelper.Name;
                                        ((Ext.Net.Image)control).FieldLabel = infoAttribute.HeadLine;
                                        //panel.Items.Add((Ext.Net.Image) control);
                                        typeToCast = typeof (Ext.Net.Image);
                                        break;
                                    case PropertyTypeAttrib.TextFractional:
                                        control = (Control)new Ext.Net.NumberField();
                                        ((NumberField)control).AllowDecimals = true;
                                        ((NumberField)control).DecimalPrecision = infoAttribute.Fractional;
                                        ((NumberField)control).MinValue = 0;
                                        ((Ext.Net.NumberField)control).FieldLabel = infoAttribute.HeadLine;
                                        control.ID = propertyHelper.Name;
                                       //panel.Items.Add(
                                            //(Ext.Net.NumberField) control);
                                        typeToCast = typeof (Ext.Net.NumberField);
                                        break;
                                    case PropertyTypeAttrib.TextLarge:
                                        control = (Control)new Ext.Net.TextArea();
                                        ((TextArea)control).FieldLabel = infoAttribute.HeadLine;
                                        control.ID = propertyHelper.Name;
                                        //panel.Items.Add((TextArea)control);
                                        typeToCast = typeof (TextArea);
                                        break;
   }
   panel.Items.Add((typeToCast)control);//that's what i need to do.

получил ошибку в строке panel.Items..... не может разрешить этот тип символаToCast

Кто-нибудь делал что-то подобное раньше?

Спасибо за аванс :)

Решено:

Что я сделал, так это привёл свой готовый элемент управления к типу Component. panel.Items.Add((Component)control);


person Harry89pl    schedule 11.04.2012    source источник


Ответы (2)


С помощью небольшого рефакторинга вы сможете получить тот же результат, не используя много приведения. В следующем примере демонстрируется очень упрощенный подход.

Пример

<%@ Page Language="C#" %>

<%@ Import Namespace="Panel=Ext.Net.Panel" %>
<%@ Import Namespace="Button=Ext.Net.Button" %>

<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!X.IsAjaxRequest)
        {
            this.Form.Controls.Add(this.BuildForm());
        }
    }

    private Component BuildForm()
    {
        var panel = new FormPanel {
            Title = "Example",
            Width = 350,
            Height = 215,
            Padding = 5,
            DefaultAnchor = "100%",
            Buttons = { new Button { Text = "Submit" }}
        };

        panel.Items.Add(this.BuildWidget(new Widget {
            Name = "text",
            ID = "TextField1",
            Label = "My TextField"
        }));

        panel.Items.Add(this.BuildWidget(new Widget {
            Name = "date",
            ID = "DateField1",
            Label = "My DateField"
        }));

        return panel;
    }

    private Field BuildWidget(Widget widget)
    {
        Field field = null;

        switch(widget.Name)
        {
            case "text":
                field = new TextField(); 
                break;
            case "date":
                field = new DateField();
                break;
        }

        field.ID = widget.ID;
        field.FieldLabel = widget.Label;

        return field;
    }

    public class Widget
    {
        public string Name { get; set; }

        public string ID { get; set; }
        public string Label { get; set; }
    }
</script>

<!DOCTYPE html>

<html>
<head runat="server">
    <title>Ext.NET Example</title>
</head>
<body>
    <form runat="server">
        <ext:ResourceManager runat="server" />

    </form>
</body>
</html>
person geoffrey.mcgill    schedule 11.04.2012

Ну, ошибка в том, что часть типа выражения приведения должна быть именем типа (или параметром типа), а не значением выражения.

Почему вы вообще должны участвовать в кастинге? Почему бы просто не:

panel.Items.Add(new Ext.Net.NumericField());

Почему у вас вообще есть актерский состав Control? Разве NumericField уже не происходит от Control? Почему вы используете typeof? В принципе, я не вижу необходимости в каких-либо приведениях в представленном вами коде. Если вы считаете, что для них есть веская причина, пожалуйста, добавьте к вопросу больше контекста.

person Jon Skeet    schedule 11.04.2012
comment
потому что я создаю свою форму динамически, и я не знаю, какой тип там будет - person Harry89pl; 11.04.2012
comment
@harry180: То есть код, который вы представили, на самом деле не соответствует тому, что вы будете делать? Я предлагаю вам изменить его на более подходящий пример. Я вижу, что вам, возможно, потребуется выполнить приведение к Control, но это все... - person Jon Skeet; 11.04.2012
comment
@ harry180: Вы до сих пор не объяснили, почему это не сработает, если вы используете panel.Items.Add(control) в последней строке. Как вы думаете, зачем вам нужен этот состав? - person Jon Skeet; 11.04.2012
comment
потому что Control это тип, который я не могу поместить в Ext.Net.Panel к нему я могу поместить только элементы управления из Ext.Net пространства имен - person Harry89pl; 11.04.2012
comment
@harry180: Есть ли базовый класс, который можно использовать в Ext.Net.Panel? например ExtControl? Я сомневаюсь, что существует отдельная перегрузка Add для каждого типа управления. (Во всяком случае, я очень надеюсь, что нет.) РЕДАКТИРОВАТЬ: Предполагая, что я нашел нужную документацию, я подозреваю, что вы хотите привести к Ext.Net.Component. - person Jon Skeet; 11.04.2012
comment
Я хочу привести к определенному типу, а не к Ext.Net.Component - person Harry89pl; 11.04.2012
comment
@harry180: Но почему? Он будет вызывать тот же метод и иметь тот же эффект, верно? Как вы думаете, какая разница? - person Jon Skeet; 11.04.2012
comment
это другое, когда я пытаюсь поместить Control в Ext.Net.Panel, я получаю сообщение об ошибке, когда я привожу тип, который на самом деле контролирует, все в порядке :), но я хочу сделать это после всех операторов, а не в каждом операторе - person Harry89pl; 11.04.2012
comment
@harry180: Боюсь, я вообще не мог понять этот комментарий, но я предлагаю, чтобы ваша последняя строка была: panel.Items.Add((Component) control); Или вместо этого измените переменную control на тип Component. Вы можете полностью избавиться от typeToCast. - person Jon Skeet; 11.04.2012
comment
Обратите внимание, что вы можете переместить назначение control.ID и, возможно, назначение control.FieldLabel за пределы вашего блока переключателей таким же образом... - person Jon Skeet; 11.04.2012
comment
@ harry180: Похоже, вы нашли решение, но, как упомянул Джон-Скит, вы навязываете много ненужного кастинга, который может (должен) не требоваться. Я создал очень упрощенный образец, который может помочь переработать ваш первоначальный подход, но мне придется опубликовать полный образец кода в новом ответе, чтобы получить читаемое форматирование. - person geoffrey.mcgill; 11.04.2012