0

So here's what I want to do. I want to take a list of phrases, and in certain parts of the phrases, indicate that user input is required.. be it a dropdown list, a textbox, a date field, etc. Kind of like Madlibs in a way.. but with the option of selecting things from a list.

For example:

I own a ?list_of_cars?, I purchased it on ?date?. It has ?freetext? miles on it.

This string gets broken apart into a mixture of text and HTML form fields/ASP.net controls.

?list_of_cars? gets turned into a dropdown list with a few options to choose from.

?date? gets turned into a date field (custom user control I created)

?freetext? is simply a textbox that the user can enter information into.

I have about 50 of these phrases that I need to work with. The end result is that they will end up being plain text in a textbox after the user fills out the required input.

No lists need a large number of options.. cars was kind of a bad example. The most options a list would contain would be 5 probably.

At this point, I started storing the entire string with a number of delimiters and placeholders into a database table.

For example, one row looks like this:

I own a {list^Nissan,Ford,Chevy}, I purchased it on {date}. It has {text} miles on it.

Then I break it down and replace the placeholders with form fields.. then put it all back together into pure text. I feel like there might be a smarter/better way to do this. I'm not opposed to backing up and changing how the initial phrases are stored.

Just curious if anyone might have any tips/suggestions?

4

2 回答 2

1

以下是您必须考虑的不同方面的一些细节

存储列表

我建议您创建两个表 List (ListID, ListName) 和 ListItem (ListID, ItemName) 并将这些数据保存在数据库中以便于维护。如果您有多个相同的汽车列表,您需要稍后更新,这将使您的事情变得容易。另一方面,更新几个字符串并不像这样容易。

标签

需要制作这些以便易于解析。我会避免使用复杂的名称,例如“{list^Nissan,Ford,Chevy}”,并将其定义为 ?list_ID?。所有标签都需要易于识别。也许?tag_name?这不是一个好主意,因为您会有问号,这可能会使解析更加困难。最好使用 #!tag_name!#

ASP.NET

所有控件都需要添加到 OnInit 方法中,而不是稍后在 Page_Load 中。

解析

这里有一些东西可以帮助你入门,但它需要更多的工作。

private const string OPEN_TAG = "!#";
private const string CLOSE_TAG = "#!";

private void Parse(string s)
{        
    int tagOpenIndex = 0;
    int tagCloseIndex = 0;

    tagOpenIndex = s.IndexOf(OPEN_TAG);

    string tag = string.Empty;

    while (tagOpenIndex >= 0)
    { 
        //Write everything before current tag opening 
        Response.Write(s.Substring(tagCloseIndex, tagOpenIndex));

        //Find where current tag is closing 
        tagCloseIndex = s.IndexOf(CLOSE_TAG, tagOpenIndex);

        //Get tag name
        tag = s.Substring(tagOpenIndex, tagCloseIndex - tagOpenIndex + 1);

        //Parse tag and create asp.net controls. Let's say this is a text box
        //You'll need to figure out where to put this and such
        //And also how to keep track of different control IDs so you can use these later.
        TextBox t = new TextBox();
        t.ID = "Generate some ID";
        Form.Controls.Add(t);

        //Get the index of next open tag
        tagOpenIndex = s.IndexOf(OPEN_TAG, tagCloseIndex);
    }
}
于 2013-05-21T09:00:14.423 回答
0

我会采用与您类似的方法,但您创建的控件可以读取编辑器的类型以及可用值。

而且我会使用 String.Format 将它们分开存储,这样你就可以重复使用

所以我会有一个有两个属性的类

class RequiredInput
{
    public property string Phrase { get; set;}
    public property Field[] Fields { get; set;}
}

class Field
{
    public Type Type { get; set;}
    public object Default { get; set;}
    public object[] options { get; set;}
}

然后我会写下这样的解析器:

var sentence = new RequiredInput();
sentence.Phrase = "I own a {0}, I purchased it on {1}. It has {2} miles on it.";
sentece.options = new Field[] { 
    new field(typeof(ComboBox), new string[] { "Car1", "Car2", "Car3"}),
    new field(typeof(DateEdit), DateTime.Now),
    new field(typeof(TextEdit), String.Empty) }
}

不知道,只是想……

于 2013-05-21T07:41:08.583 回答