Сделать строку [] как серию редактируемых элементов управления? - PullRequest
0 голосов
/ 25 августа 2009

У меня есть строка [], содержащая отдельные слова, выделенные из абзаца текста. Мне нужно отобразить каждое слово в отдельной ячейке, и каждой ячейке должна быть назначена динамическая ширина в зависимости от длины слова. Я хочу, чтобы в максимальной ширине каждой строки было как можно больше слов.

Короче говоря, я пытаюсь взять данный абзац текста и представить его как серию редактируемых элементов управления способом, который напоминает то, как он может выглядеть как простой текстовый документ, причем каждое слово занимает только необходимое место на каждая "строка".

Сначала я попытался использовать DataList с RepeatLayout в табличном режиме и RepeatColumns до установленного значения 10 с Repeater внутри, содержащим элемент управления Label; это привело к 10 словам в строке, но каждая ячейка с фиксированной шириной.

Я рассмотрел возможность использования GridView с одним столбцом, в который я бы поместил столько слов (в виде элементов управления Label) на строку, сколько поместится, добавляя новые строки по мере необходимости, пока не будет построен весь абзац.

Может ли кто-нибудь поделиться элегантным способом сделать это?

Ответы [ 3 ]

1 голос
/ 25 августа 2009

Я начну с того, что, с точки зрения пользовательского интерфейса, я не совсем уверен, почему вам нужно это сделать, но если это нужно сделать, вы бы сделали что-то вроде этого:

  • Начните с вашей строки []
  • Создать List<List<string>>
  • Переберите исходный массив, добавив строки в новый List<string>
  • Как только вы достигнете желаемой общей длины символов, добавьте List<string> к вашему List<List<string>> (который содержит ваши строки)
  • Повторяйте эти шаги, пока вы не пройдете весь свой первоначальный массив

Как только это будет сделано, вы привязываете список списков к повторителю, как показано ниже (псевдокод; может быть, немного отключен):

<asp:Repeater id="rpt1" runat="server">
<ItemTemplate>
  <div>
    <asp:Repeater id="rpt2" runat="server" DataSource='<%# Container.DataItem %>'>
    <ItemTemplate>
       <asp:TextBox id="txt1" runat="server" Text='<%# Container.DataItem %>' Width='<%# MyWidthAlgorithm(Container.DataItem) %>'
    </ItemTemplate>
    </asp:Repeater>
  </div>
</ItemTemplate>
</asp:Repeater>
1 голос
/ 25 августа 2009

Волшебство, которое вы ищете, является атрибутом contenteditable. Работает в IE, Firefox и Chrome.

Я не уверен, что, черт возьми, вы делаете с этим, Имао ... но это должно сработать:

Ваш код за:

protected void Page_Load(object sender, EventArgs e)
{
    //creating some bogus collection of strings.
    string[] parts = { "this", "is", "a", "test", "of", "the", "goofiest", "ui", "ever" };
    //bind it to the repeater.
    rptr.DataSource = parts;
    rptr.DataBind();
    //now we'll add them to a JavaScript array we can access client side.
    StringBuilder sb = new StringBuilder();
    sb.Append("document.stringItems = new Array();");
    for (int i = 0; i < parts.Length; i++)
        sb.AppendFormat("document.stringItems[{0}] = '{1}';", i, parts[i]);
    ScriptManager.RegisterClientScriptBlock(this, GetType(), "someKey", sb.ToString(), true);
}
protected void btnTest_Click(object sender, EventArgs e)
{
    //display the result just so we can see it's working.
    lblResult.Text = hdnResult.Value;
}

Ваш .ASPX:

<asp:Repeater ID="rptr" runat="server">
    <ItemTemplate>
        <span contenteditable="true" style="border: solid 1px;" onkeyup="updateItem(event, <%#Container.ItemIndex%>)">
            <%#Container.DataItem%></span>
    </ItemTemplate>
</asp:Repeater>
<asp:HiddenField ID="hdnResult" runat="server" />
<asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click" />
<script type="text/javascript" language="javascript">
    //<![CDATA[
    function updateItem(e, index) {
        //get the source element. (magic here for cross browser lameness)
        var src;
        if(window.event) {
            e = window.event;
            src = e.srcElement;
        }else{
            src = e.target;
        }
        //update our item in our array.
        document.stringItems[index] = src.innerHTML;
        //update our hidden field.
        var s = '';
        var space = false;
        for (var i = 0; i < document.stringItems.length; i++) {
            if (space)
                s += ' ';
            else
                space = true;
            s += document.stringItems[i];
        }
        var hdnResult = document.getElementById('<%=hdnResult.ClientID%>');
        hdnResult.value = s;
    }
    //]]>
</script>
<asp:Label ID="lblResult" runat="server"></asp:Label>

Вы должны будете добавить немного javascript для onkeypress, чтобы убедиться, что они не добавляют возврат каретки или пробелы или что-то еще, что вы не хотите, чтобы они вставляли ... но это основная идея.

Надеюсь, это поможет. Удачи.

0 голосов
/ 25 августа 2009

Лучший способ приблизиться к чему-то подобному - просто использовать ретранслятор и пропустить все, что осталось.

<asp:Repeater runat="server" id="rptr">
   <ItemTemplate>
      <span style="float:left; height:22px; line-height:22px;"><%# Eval("Word") %></span>
   </ItemTemplate>
</asp:Repeater>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...