3

我有一个基类、一组子类和一个集合容器,用于使用局部视图动态创建和填充控件。

// base class
public class SQControl
{
    [Key]
    public int ID { get; set; }
    public string Type { get; set; }
    public string Question { get; set; }
    public string Previous { get; set; }
    public virtual string Current { get; set; }
}

// subclass
public class SQTextBox : SQControl
{
    public SQTextBox()
    {
        this.Type = typeof(SQTextBox).Name;
    }
}

//subclass
public class SQDropDown : SQControl
{
    public SQDropDown()
    {
        this.Type = typeof(SQDropDown).Name;
    }

    [UIHint("DropDown")]
    public override string Current { get; set; }
} 

// collection container used as the Model for a view
public class SQControlsCollection
{
    public List<SQControl> Collection { get; set; }
    public SQControlsCollection()
    {
        Collection = new List<SQControl>();
    }

}

我在运行时根据需要使用 SQControl 的不同子类填充 Collection 控件,并且在 EditorTemplates 中我为每个子类提供了单独的视图。在集合项目上使用 Html.EditorFor 我可以使用适当的控件动态生成表单。

这一切都很好。

我遇到的问题是,当我保存表单时,MVC 绑定无法判断 Collection 中的每个项目是用什么子类创建的,而是将它们绑定到基类 SQControl 的实例。

这会使视图引擎感到困惑,因为它无法确定要加载的正确视图,而只是加载默认视图。

我目前的解决方法是将子类的“类型”保存为模型中的一个字段,然后在回发时,我将集合复制到一个新容器中,根据中的信息使用正确的子类重新创建每个对象类型字段。

public static SQControlsCollection Copy(SQControlsCollection target)
    {
        SQControlsCollection newCol = new SQControlsCollection();

        foreach (SQControl control in target.Collection)
        {
            if (control.Type == "SQTextBox")
            {
                newCol.Collection.Add(new SQTextBox { Current = control.Current, Previous = control.Previous, ID = control.ID, Question = control.Question });
            }
            else if (control.Type == "SQDropDown")
            {
                newCol.Collection.Add(new SQDropDown { Current = control.Current, Previous = control.Previous, ID = control.ID, Question = control.Question });
            }
            ...


        }

        return newCol;
    }

所以我的问题是,有没有更好的方法来维护回发之间的基本类型集合中的项目类型?我知道在 MVC 中为每个模型都有一个类型化的视图是一种做法,但我希望能够使用可重用的部分视图基于 XML 文档动态构建视图。

4

0 回答 0