powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Медленный WrapPanel
13 сообщений из 13, страница 1 из 1
Медленный WrapPanel
    #37760897
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
Медленный WrapPanel
    #37761050
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WrapPanel,

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

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

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

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

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

ок. большое спасибо!
...
Рейтинг: 0 / 0
Медленный WrapPanel
    #37762403
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
Медленный WrapPanel
    #37762502
WrapPanel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, кстати, как заставить элемент, не попавший в окошко не отрисовываться?
...
Рейтинг: 0 / 0
Медленный WrapPanel
    #37762529
AlexeiK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WrapPanel,

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

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

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

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


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