Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Медленный WrapPanel / 13 сообщений из 13, страница 1 из 1
19.04.2012, 13:30
    #37760897
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
Есть проблема с быстродействием.
Делаю UserControl, на него, упрощая описание задачи, динамически добавляю несколько тысяч кнопок.
Кнопки должны занимать все пространство.

xaml:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
<UserControl x:Class="Desktop.PrinterControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="301" d:DesignWidth="323">

    <UserControl.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <Grid >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="SingleWidthColumn"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Button Content="{Binding Path=Name}" Height="23"/>
            </Grid>
        </DataTemplate>
    </UserControl.Resources>
    
    <Grid>
        <ListBox Grid.IsSharedSizeScope="True" Grid.Row="1" Margin="3" Name="lstPrinters"  ItemTemplate="{StaticResource ItemTemplate}"
             ScrollViewer.HorizontalScrollBarVisibility="Disabled" SnapsToDevicePixels="True">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel></WrapPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </Grid>
</UserControl>

Для нескольких тысяч кнопок получается ну очень медленно.

Без WrapPanel:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
<UserControl x:Class="Desktop.PrinterControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="301" d:DesignWidth="323">

    <UserControl.Resources>
        <DataTemplate x:Key="ItemTemplate">
            <Grid >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition SharedSizeGroup="SingleWidthColumn"></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Button Content="{Binding Path=Name}" Height="23"/>
            </Grid>
        </DataTemplate>
    </UserControl.Resources>
    
    <Grid>
        <ListBox Grid.IsSharedSizeScope="True" Grid.Row="1" Margin="3" Name="lstPrinters"  ItemTemplate="{StaticResource ItemTemplate}"
             ScrollViewer.HorizontalScrollBarVisibility="Disabled" SnapsToDevicePixels="True">
        </ListBox>
    </Grid>
</UserControl>

получается быстренько, как и надо.

Вопрос - как повысить быстродействие в первом случае, когда несколько тысяч кнопок нужно раскидать по всему доступному пространству?
...
Рейтинг: 0 / 0
19.04.2012, 14:25
    #37761050
AlexeiK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
WrapPanel,

да тут все просто.
в тормозном варианте, у тебя wrappanel создает все контролы сразу.
в быстром, они создаются, только когда попадают в область видимости.
...
Рейтинг: 0 / 0
19.04.2012, 14:31
    #37761071
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
AlexeiK,

ок. а как мне добиться ситуации, когда и контролы раскиданы по всему полю, и работает быстро?
...
Рейтинг: 0 / 0
19.04.2012, 14:40
    #37761093
AlexeiK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
WrapPanel,

тебе нужно унаследоваться от virtualizingstackpanel
и переопределить measure и arrange методы.
...
Рейтинг: 0 / 0
19.04.2012, 14:40
    #37761094
AlexeiK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
а потом свою панель подсунуть в itemscontrol.
...
Рейтинг: 0 / 0
19.04.2012, 14:46
    #37761111
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
AlexeiK,

ок. прошу прощения, а как именно переопределить? есть где-нибудь примерчик?
...
Рейтинг: 0 / 0
19.04.2012, 14:58
    #37761145
AlexeiK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
WrapPanel,

->
...
Рейтинг: 0 / 0
19.04.2012, 15:00
    #37761153
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
AlexeiK,

ок. большое спасибо!
...
Рейтинг: 0 / 0
20.04.2012, 10:11
    #37762403
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
Продолжу тему. Сделал свою панель, но унаследовал от Panel. Вроде работает.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
public class PlotPanel : Panel
{
    public PlotPanel()
        : base()
    {
    }

    protected override Size MeasureOverride(Size constraint)
    {
        Size currentLineSize = new Size();
        Size panelSize = new Size();

        foreach (UIElement element in this.Children)
        {
            element.Measure(constraint);
            Size desiredSize = element.DesiredSize;

            if (currentLineSize.Width + desiredSize.Width > constraint.Width)
            {
                panelSize.Height += currentLineSize.Height;
                panelSize.Width = Math.Max(currentLineSize.Width, panelSize.Width);
                currentLineSize = desiredSize;

                if (desiredSize.Width > constraint.Width)
                {
                    panelSize.Width = Math.Max(desiredSize.Width, panelSize.Width);
                }
            }
            else
            {
                currentLineSize.Width += desiredSize.Width;
                currentLineSize.Height = Math.Max(desiredSize.Height,
                currentLineSize.Height);
            }
        }

        panelSize.Width = Math.Max(currentLineSize.Width, panelSize.Width);
        panelSize.Height += currentLineSize.Height;

        return panelSize;
    }

    protected override Size ArrangeOverride(Size arrangeBounds)
    {
        Size currentLineSize = new Size();
        double totalHeight = 0;

        foreach (UIElement element in this.Children)
        {
            Size desiredSize = element.DesiredSize;
            if (currentLineSize.Width + desiredSize.Width > arrangeBounds.Width)
            {
                totalHeight += currentLineSize.Height;
                currentLineSize = new Size();
            }
            currentLineSize.Height = Math.Max(desiredSize.Height, currentLineSize.Height);

            element.Arrange(new Rect(currentLineSize.Width, totalHeight, element.DesiredSize.Width, element.DesiredSize.Height));

            currentLineSize.Width += desiredSize.Width;
        }

        totalHeight += currentLineSize.Height;
        return new Size(arrangeBounds.Width, totalHeight);
    }
}



Наследую от VirtualizingStackPanel - работает, но ничего не показывает. В чем может быть проблема?
...
Рейтинг: 0 / 0
20.04.2012, 11:02
    #37762502
WrapPanel
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
Да, кстати, как заставить элемент, не попавший в окошко не отрисовываться?
...
Рейтинг: 0 / 0
20.04.2012, 11:14
    #37762529
AlexeiK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
WrapPanel,

Вся фишка в том, что в VSP в этих методах, находится код, который не только размещает элементы.
А еще и код, который их создает :)
поэтому у тебя ничего не вышло при наследовании.

Элемент не отрисовываться заставляет лишь только реализация интерфейса IScrollInfo у твоего класса панели.

Собоственно VSP и сделана из Panel и IScrollInfo.

Поэтому посмотри рефлектором код в этих методах у VSP
или допиши свой класс, реализова еще и IScrollInfo
тут пример ->
...
Рейтинг: 0 / 0
21.04.2012, 10:19
    #37764270
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
тынц , тынц2 , и тд, гугл в руки
...
Рейтинг: 0 / 0
21.04.2012, 10:20
    #37764271
SeVa
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Медленный WrapPanel
пропустил тынц3
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Медленный WrapPanel / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]