Как максимизировать эффективность FlowLayoutPanel?

Основная цель - создать визитную карточку для каждого контакта и поместить эту карточку в FlowLayoutPanel. Сама карта состоит примерно из 10 ярлыков и 3 комбинированных списков.

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

Однако основная проблема - это сбои. Требуется всего около 200 карт, чтобы сломаться (кончились ручки).

Я согласен, что существуют методы разбиения по страницам, которые можно реализовать, поскольку пользователю никогда не нужно будет видеть больше, чем поместится на 1 или 2 экранах за раз, но написание подпрограмм разбиения по страницам может быть довольно сложным.

Есть предложения о том, как максимизировать эффективность запланированной FlowLayoutPanel?

P.S. Основная проблема - нехватка ручек (слишком много элементов управления на панели). Необходимо решить эту проблему, прежде чем беспокоиться о скорости.


person user1646737    schedule 24.09.2012    source источник
comment
Это может дать вам несколько подсказок: stackoverflow.com / questions / 835100 /   -  person rene    schedule 24.09.2012
comment
Спасибо за быстрый ответ, Рене. Меня больше всего беспокоит проблема нехватки ручек. Если я не решу эту проблему, нет смысла беспокоиться о скорости.   -  person user1646737    schedule 24.09.2012
comment
У вас нет другого выбора, чтобы сделать ваш потоковый макет виртуальным (или страницу, что более удобно)   -  person rene    schedule 24.09.2012
comment
Я этого боялся. На каждой визитке есть выпадающие списки. Итак, я не могу просто визуализировать их как растровые изображения. Остается попытаться реализовать какой-то метод разбиения на страницы. Я могу взломать его, но надеюсь, что кто-то делал это раньше и может указать мне пример.   -  person user1646737    schedule 24.09.2012
comment
Очевидным решением является ListBox с именами контактов и одной визитной карточкой для просмотра / редактирования выбранного.   -  person Hans Passant    schedule 24.09.2012
comment
Что ж, я полагаю, если вы хотите отказаться от желаемого внешнего вида пользовательского интерфейса, это вариант. Я не чувствовал, что готов так быстро сдаться. Я изменил автопрокрутку FlowPanel на false. Я добавил Hscroll прямо под панелью. Я установил для свойств LargeChange и Maximum полосы прокрутки количество карточек на странице и общее количество карточек соответственно. Затем я устанавливаю событие прокрутки для Hscroll. Когда событие показывает EndScroll, я проверяю hscroll.value, который сообщает мне, на какой странице я нахожусь. Затем, если страница изменилась (я сохраняю значение старой страницы), я очищаю панель. Продолж.   -  person user1646737    schedule 24.09.2012
comment
После очистки панели я добавляю из общего списка контактов, начиная с того, который находится в (scroll.value * LargeMove) + 1. Я продолжаю добавлять контакты по порядку до номера элемента (scroll.value * LargeMove) + 1 + LargeMove. Это работает. Теперь мне нужно немного очистить, но это работает. Я описал этот процесс довольно грубо, и мои математические расчеты могут отличаться на 1 карту. Но для тех, кто в будущем, кажется, что это делается именно так.   -  person user1646737    schedule 24.09.2012
comment
максимальный размер обработчика окна составляет 10 КБ , это ограничение ядра Windows, и вы не можете его перепрыгнуть. Единственное возможное решение - пейджинг.   -  person shfire    schedule 04.07.2013


Ответы (1)


Хорошо, а как насчет:

Создайте класс для хранения информации, необходимой для воссоздания визитной карточки (10 меток и 3 поля со списком) в виде общедоступных, получаемых / устанавливаемых свойств и с пустым общедоступным конструктором по умолчанию. Затем сериализуйте каждую визитную карточку как файл xml (или двоичный файл), используя XmlSerializer, в одну папку. Затем вы можете использовать что-то вроде string[] businessCards = Directory.GetFiles(Path.GetFullPath("mysettings\\businesscards")); для перебора своего длинного «кешированного» списка визитных карточек. Имейте класс, который управляет добавлением / удалением элементов из вашего FlowLayoutPanel, вызывая такую ​​функцию, как: SerializableBusinessCardClass GetNextCard() {}. Это было бы довольно просто реализовать. Вы также можете сериализовать List<SerializableBusinessCardClass> длиной около 5 (или столько, сколько вы хотите загрузить сразу) в один XML-файл для максимальной эффективности, или если у вас действительно невероятное количество визитных карточек (например, проводник лагает, когда просмотр папки). Хотя двоичная сериализация будет быстрее, подход XML имеет дополнительное преимущество, заключающееся в том, что ваши клиенты могут указывать новые визитные карточки, которые они хотят, чтобы вы отображали, создав файл XML самостоятельно.

Здесь я дам вам конкретный пример того, как вы создадите и сериализуете такую ​​структуру данных:

public class SerializableBusinessCard
{
    public SerializableBusinessCard()       { }
    public string Name                      { get; set; }
    public string Company                   { get; set; }
    public List<string> Labels              { get; set; }
    public List<ComboItem> ComboBoxes       { get; set; }

}

public class ComboItem
{   
    public ComboItem()              { }
    public string Name              { get; set; }
    public string Text              { get; set; }
    public int SelectedIndex        { get; set; }
    public Point Location           { get; set; }
    public Size size                    { get; set; }
    public List<string> Collection{ get; set; }
}

Использование:

    public void stackoverflow_BusinessCard_FlowLayoutPanel()
    {
        List<string> labels = new List<string>();

        labels.Add("Title");
        labels.Add("Description");
        labels.Add("Phone");
        labels.Add("Email");
        labels.Add("Address");
        labels.Add("label6");
        labels.Add("labelN");


        ComboItem cItem = new ComboItem();

        cItem.Collection = new List<string>();
        cItem.Collection.Add("Option1");
        cItem.Collection.Add("Option2");

        cItem.Name = "comboName";
        cItem.SelectedIndex = 0;
        cItem.Text = cItem.Collection[cItem.SelectedIndex];
        cItem.Location = new Point(50, 265);
        cItem.size = new Size(100,21);

        List<ComboItem> comboItems = new List<ComboItem>();
        comboItems.Add(cItem);


        SerializableBusinessCard bCard1 = new SerializableBusinessCard();

        bCard1.Name         = "CompanyXYZ_BlueTheme";
        bCard1.Company      = "CompanyXYZ";
        bCard1.Labels       = labels;
        bCard1.ComboBoxes   = comboItems;

        SerializeObjectXML("BusinessCard_392.xml",bCard1);

        SerializableBusinessCard loaded = DeserializeBusinessCardXML("BusinessCard_392.xml");
    }

Вот функция сериализации:

    public void SerializeObjectXML(string filename,object obj)
    {
        using(StreamWriter streamWriter = new StreamWriter(filename))
        {
            XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
            xmlSerializer.Serialize(streamWriter,obj);
        }
    }

Результат:

<?xml version="1.0" encoding="utf-8"?>
<SerializableBusinessCard xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>CompanyXYZ_BlueTheme</Name>
  <Company>CompanyXYZ</Company>
  <Labels>
    <string>Title</string>
    <string>Description</string>
    <string>Phone</string>
    <string>Email</string>
    <string>Address</string>
    <string>label6</string>
    <string>labelN</string>
  </Labels>
  <ComboBoxes>
    <ComboItem>
      <Name>comboName</Name>
      <Text>Option1</Text>
      <SelectedIndex>0</SelectedIndex>
      <Location>
        <X>50</X>
        <Y>265</Y>
      </Location>
      <size>
        <Width>100</Width>
        <Height>21</Height>
      </size>
      <Collection>
        <string>Option1</string>
        <string>Option2</string>
      </Collection>
    </ComboItem>
  </ComboBoxes>
</SerializableBusinessCard>

И десериализатор:

        public static SerializableBusinessCard DeserializeBusinessCardXML(string filename)
        {
            SerializableBusinessCard result = new SerializableBusinessCard();
            using(StreamReader streamReader = new StreamReader(filename))
            {
                XmlSerializer xmlReader = new XmlSerializer(typeof(SerializableBusinessCard));
                result = (SerializableBusinessCard) xmlReader.Deserialize(streamReader);
            }
            return result;
        }

Надеюсь это поможет.

person Adam White    schedule 05.08.2013