Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 05.08.2017
Сообщений: 45
1
WPF

Оптимизация большого количества пользовательских элементов управления

31.01.2019, 11:58. Показов 2599. Ответов 7

Author24 — интернет-сервис помощи студентам
Задача такова: необходимо создать элемент управления с предложением в котором выделяется каждое слово (слово при наведении выделяется привязано событие на клик и т.д. и т.п.) номером в списке и кнопкой удаления.
Вот что у меня получилось:
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
31
32
33
<UserControl x:Class="WpfApp2.PhraseInList"
             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" 
             xmlns:local="clr-namespace:WpfApp2"
             mc:Ignorable="d" 
             d:DesignHeight="22" d:DesignWidth="400">
    <Grid Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" Height="22">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="45"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="22"/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center" Name="NumberText" Text="0:" Margin="0,0,5,0"  />
        <StackPanel Grid.Column="1" Orientation="Horizontal" Name="PhraseStack">
            <StackPanel.Resources>
                <Style TargetType="{x:Type TextBlock}">
                    <Setter Property="Margin" Value="0,0,4,0"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="HorizontalAlignment" Value="Left"/>
                    <EventSetter Event="TextBlock.MouseEnter" Handler="TextBlock_MouseEnter"/>
                    <EventSetter Event="TextBlock.MouseLeave" Handler="TextBlock_MouseLeave"/>
                    <EventSetter Event="TextBlock.MouseDown" Handler="TextBlock_MouseDown"/>
                </Style>
            </StackPanel.Resources>
        </StackPanel>
        <Button Grid.Column="2" Margin="1" Click="Button_Click">
            <Image Source="/Images/button-delete.png"/>
        </Button>
 
    </Grid>
</UserControl>
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
    public partial class PhraseInList : UserControl
    {
        public delegate void WordClickEventHandler(int id, string word);
        public event WordClickEventHandler ClickWord = delegate { };
        public delegate void DeleteEventHandler(int id);
        public event DeleteEventHandler Delete = delegate { };
        private Brush enterBrush = SystemColors.ControlDarkBrush;
        private Brush leaveBrush = SystemColors.WindowBrush;
        private Brush selectedBrush = SystemColors.GradientActiveCaptionBrush;
        private int id;
 
        public PhraseInList()
        {
            InitializeComponent();
        }
 
        public PhraseInList(int id, int number, string[] words, bool selected)
        {
            InitializeComponent();
            NumberText.Text = number.ToString() + ":";
            if (selected)
                this.Background = selectedBrush;
            for (int i  = 0; words[i] != ""; i++)
            {
                TextBlock word = new TextBlock();
                word.Text = words[i];
                PhraseStack.Children.Add(word);
            }
 
        }
 
        private void TextBlock_MouseEnter(object sender, MouseEventArgs e)
        {
            TextBlock word = sender as TextBlock;
            word.Background = enterBrush;
        }
 
        private void TextBlock_MouseLeave(object sender, MouseEventArgs e)
        {
            TextBlock word = sender as TextBlock;
            word.Background = leaveBrush;
        }
 
        private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
        {
            TextBlock word = sender as TextBlock;
            ClickWord(id, word.Text);
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Delete(id);
        }
    }
Проблема такая: этих элементов в StackPannel должно быть очень много (порядка 15000) и создание этого списка выходит очень долгой.
Есть ли какие-нибудь способы это ускорить?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.01.2019, 11:58
Ответы с готовыми решениями:

Добавление пользовательских элементов управления по нажатию на кнопку
Создал UserControl с названием ProductPanel. Как добавить его по нажатию на кнопку. Есть метод: ...

Оптимизация хранения большого количества объектов в Dictionary
Добрый день. Имеется некий класс Quest и список public static Dictionary&lt;Subject, Dictionary&lt;byte,...

Оптимизация большого количества NPC на карте
Пытаюсь сделать Терарию на C#(без Unity и т.д).В этой игре есть довольно большая карта, на которой...

Оптимизация обработки большого количества объектов
Доброго времени суток, господа. У меня есть графическая программа на основе SFML. В программе...

7
1514 / 905 / 328
Регистрация: 17.05.2015
Сообщений: 3,417
31.01.2019, 12:27 2
Цитата Сообщение от Гуся Посмотреть сообщение
Есть ли какие-нибудь способы это ускорить?
Если элементы типовые, то можно написать шаблон для листбокса/листвью
0
1577 / 583 / 183
Регистрация: 05.12.2015
Сообщений: 936
31.01.2019, 13:27 3
за пять минут что-то кривое написал
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
      <RichTextBox>
         <RichTextBox.Resources>
            <Style TargetType="Run">
               <EventSetter Event="MouseEnter" Handler="mouseEnter"/>
               <EventSetter Event="MouseLeave" Handler="mouseLeave"/>
               <EventSetter Event="PreviewMouseLeftButtonDown" Handler="mouseClick"/>
            </Style>
         </RichTextBox.Resources>
         <FlowDocument>
            <Paragraph x:Name="parag">
               <Run>Text 1</Run>
               <Run>Text 2</Run>
               <Run>Text 3</Run>
               <Run>long Text for 1</Run>
               <Run>long Text for 3</Run>
               <Run>long Text for 4</Run>
            </Paragraph>
         </FlowDocument>
      </RichTextBox>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
      private void mouseEnter ( object sender, MouseEventArgs e )
      {
         Run run = sender as Run;
         run.Background = SystemColors.HighlightBrush;
         run.Foreground = SystemColors.HighlightTextBrush;
         run.Cursor = Cursors.Hand;
      }
 
      private void mouseLeave ( object sender, MouseEventArgs e )
      {
         Run run = sender as Run;
         run.Background = parag.Background;
         run.ClearValue ( ForegroundProperty );
         run.ClearValue ( CursorProperty );
      }
      private void mouseClick ( object sender, MouseButtonEventArgs e )
      {
         if ( e.ClickCount == 1 )
         {
            Run run = sender as Run;
            parag.Inlines.Remove ( run );
         }
      }
добавлять текст надо через parag.Inlines.Add()

Добавлено через 38 минут
доп. информацию об элементе (номер в списке и т.д.) можно добавить в Run
C#
1
2
         Run run = new Run ( "some text" ) { Tag = 22 };
         parag.Inlines.Add ( run );
получить можно в любом событии через
C#
1
run.Tag
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,531
Записей в блоге: 2
31.01.2019, 16:13 4
Цитата Сообщение от Гуся Посмотреть сообщение
Вот что у меня получилось:
Получилась у Вас ерунда какая-то...
Зачем Вы используете StackPanel с программным созданием TextBox (это очень медленное решение) вместо стандартного ListBox? В чём смысл такого решения?
0
0 / 0 / 0
Регистрация: 05.08.2017
Сообщений: 45
06.02.2019, 00:27  [ТС] 5
StackPanel я использую так как мне не нужно выделение элементов (синенькие рамки)
0
Модератор
Эксперт .NET
15466 / 10712 / 2786
Регистрация: 21.04.2018
Сообщений: 31,531
Записей в блоге: 2
06.02.2019, 15:22 6
Цитата Сообщение от Гуся Посмотреть сообщение
StackPanel я использую так как мне не нужно выделение элементов (синенькие рамки)
Ну ListBox это и так делает. Вы фактически пытаетесь повторить реализацию ListBox.
0
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
06.02.2019, 17:53 7
Цитата Сообщение от Гуся Посмотреть сообщение
StackPanel я использую так как мне не нужно выделение элементов (синенькие рамки)
для того, чтобы убрать "синенькие рамки" достаточно просто переопределить стиль для ListBoxItem'a
1
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
06.02.2019, 18:53 8
делать нечего на работе, накидал примерчик
Вложения
Тип файла: zip SelectedWords.zip (738.3 Кб, 2 просмотров)
0
06.02.2019, 18:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.02.2019, 18:53
Помогаю со студенческими работами здесь

Оптимизация вывода большого (более 7000) количества записей на странице
Здравствуйте. Прошу совета, как сделать более оптимальным решение. Имеется справочник КБК....

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

Добавление пользовательских элементов управления на форму, в частности, ButtonChrome
Скачал пользовательский ЭУ из FAQ (ButtonChrome). А как его на форму поставить? :wall:

Быстрое создание большого массива элементов управления
Привет всем! У меня есть некоторый пользовательский (свой) элемент управления. Подскажите,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru