Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175

Panel не получается настроить адаптацию при открытие программы на весь экран

07.10.2023, 04:38. Показов 2117. Ответов 31
Метки c#, panel, wpf (Все метки)

Студворк — интернет-сервис помощи студентам
У меня есть панель, по типу WrapPanel, при изменение ширины элементы растягиваются и когда появляется доступное место с другой строки на доступное место переносится элемент. Это хорошо работает при изменение размера за края приложения и если я растяну на большую часть экрана и нажму кнопку развернуть на весь экран, то все отступы сохраняются

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

Видно что у строк отступы не ровные

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

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;
 
namespace Wpap_Test
{
    public class FillingPanel : Panel
    {
        // Этап подсчета занимаемого места
        protected override Size MeasureOverride(Size availableSize)
        {
            double width = 0, maxWidth = 0, y = 0, nextY = 0;
            foreach (FrameworkElement child in Children)
            {
                // Запрашиваем измерение желаемого размера
                child.Measure(availableSize);
                // Если элемент помещается в текущую строку
                if (width + child.DesiredSize.Width <= availableSize.Width)
                { 
                    // увеличиваем ширину текущей строки
                    width += child.DesiredSize.Width;
                }
                // иначе
                else
                {
                    // предполагаем размещение элемента в следующей строке
                    width = child.DesiredSize.Width;
                    y = nextY;
                }
                // Запоминаем максимальную потребную ширину
                if (width > maxWidth)
                    maxWidth = width;
                // и высоту панели
                if (y + child.DesiredSize.Height > nextY)
                    nextY = y + child.DesiredSize.Height;
            }
            return new Size(maxWidth, nextY);
        }
 
        // Этап размещения элементов
        protected override Size ArrangeOverride(Size finalSize)
        {
            double y = 0, nextY = 0, width = 0;
            // Коллекция, содержащая элементы текущей строки
            var line = new List<FrameworkElement>();
            foreach (FrameworkElement child in Children)
            {
                // Если элемент уместится в текущей строке
                if (width + child.DesiredSize.Width <= finalSize.Width)
                {
                   
                    // Подсчитываем потребную ширину строки
                    width += child.DesiredSize.Width;
                    // Подсчитываем смещение по вертикали следущей строки
                    if (y + child.DesiredSize.Height > nextY)
                        nextY = y + child.DesiredSize.Height;
                    if (width + child.DesiredSize.Width >= finalSize.Width)
                        //Задаем Margin для последнего элемента строки
                        child.Margin = new Thickness(7, 7, 7, 0);
                    else
                        //Задаем Margin для элемента строки
                        child.Margin = new Thickness(7, 7, 0, 0);
                    // Помещаем его в список элементов
                    line.Add(child);
                }
                // иначе
                else
                {
                    // Размещаем строку
                    ArrangeLine(line, finalSize.Width, y, nextY - y);
                    // Элементы следующей строки
                    line = new List<FrameworkElement> { child };
                    width = child.DesiredSize.Width;
                    y = nextY;
                    nextY = y + child.DesiredSize.Height;
                    //Задаем Margin для первого элемента новой строки
                    child.Margin = new Thickness(7, 7, 0, 0);
                }
            }
            //Задаем Margin для последнего элемента панели
            line.Last().Margin = new Thickness(7, 7, 7, 0);
            // Последняя строка
            ArrangeLine(line, finalSize.Width, y, nextY - y);
            return finalSize;
        }
 
        private void ArrangeLine(List<FrameworkElement> line, double lineWidth, double y, double lineHeight)
        {
            // Потребная ширина строки
            double width = line.Sum(fe => fe.DesiredSize.Width);
            // Делим оставшуюся часть длины строки на все элементы
            double delta = (lineWidth - width) / line.Count;
            // Смещение элемента внутри строки
            double x = 0;
            foreach (var fe in line)
            {
                // Вычисляем ширину текущего элемента
                double curWidth = fe.DesiredSize.Width + delta;
                // Размещаем элемент
                fe.Arrange(new Rect(x, y, curWidth, lineHeight));
                // Вычисляем смещение следующего
                x += curWidth;
            }
        }
    }
}
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
34
35
36
37
38
39
40
<Window x:Class="Wpap_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpap_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="745" WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <Style TargetType="{x:Type local:ItemMarginWrapPanel}">
            <Setter  Property="ItemMargin" Value="7" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid Margin="0">
            <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
            <Border Margin="14 20 14 0" CornerRadius="6" Height="40" Background="Gray">
                <TextBlock Margin="20 0 0 0" FontSize="20" VerticalAlignment="Center">Title</TextBlock>
            </Border>
            <local:FillingPanel Background="#F1F1F1F1" Grid.Row="1" Margin="0 14 0 0" >
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1E69B9B"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1653232"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1421D1D"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1FF2222"></Border>
                <Border x:Name="five" Height="100" CornerRadius="6" MinWidth="351" Background="#F10D004E"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F15135DE"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1E69B9B"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1653232"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F1421D1D"></Border>
                <Border x:Name="ten" Height="100" CornerRadius="6" MinWidth="351" Background="#F1FF2222"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F10D004E"></Border>
                <Border Height="100" CornerRadius="6" MinWidth="351" Background="#F15135DE"></Border>
            </local:FillingPanel>
        </Grid>
    </Grid>
</Window>
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.10.2023, 04:38
Ответы с готовыми решениями:

На родительской форме расположена panel, при открытие дочерней формы, она прячется под panel
Как сделать, чтобы она была сверху?

Открытие формы на весь экран
Как сделать, чтобы форма выводилась на весь экран, но панель задач была бы видна?

Открытие окна браузера во весь экран
Доброго времени суток. Хочу сделать так, как раньше у меня, собственно, и было - чтобы при загрузке приложения firefox окно браузера...

31
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
07.10.2023, 21:38
Лучший ответ Сообщение было отмечено xellan24rus как решение

Решение

Студворк — интернет-сервис помощи студентам
xellan24rus, вроде отладил:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
namespace Core2023.Topics.xellan24rus.FillingPanelArrange
{
    public class FillingPanel : Panel
    {
        /// <summary>Зазар между ячейками.</summary>
        public double Gap
        {
            get { return (double)GetValue(GapProperty); }
            set { SetValue(GapProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Gap.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GapProperty =
            DependencyProperty.Register(nameof(Gap), typeof(double), typeof(FillingPanel), new FrameworkPropertyMetadata(0d) { AffectsArrange = true });
 
 
        // Этап подсчета занимаемого места
        protected override Size MeasureOverride(Size availableSize)
        {
            // Фиксация зазора
            double gap = Gap;
 
            // Ширина-Высота и размер клиентской обюласти за вычетом зазоров по краям.
            double sizeWidth = availableSize.Width - gap - gap;
            double sizeHeight = availableSize.Height - gap - gap;
            Size contentSize = new Size(sizeWidth, sizeHeight);
 
            double currRowWidth = 0;
            double maxRowWidth = 0;
            double currRowHeight = 0;
            double sumRowsHeight = 0;
            double rowWidth = sizeWidth + gap; // Размер строки включая один зазор.
            foreach (FrameworkElement child in Children)
            {
                // Запрашиваем измерение желаемого размера
                child.Measure(contentSize);
                Size desiredSize = child.DesiredSize;
 
                double desiredWidth = desiredSize.Width + gap;
                double desiredHeight = desiredSize.Height;
 
                // Если элемент первый или помещается в текущую строку
                if (currRowWidth == 0 || currRowWidth + desiredWidth <= rowWidth)
                {
                    // увеличиваем ширину текущей строки
                    currRowWidth += desiredWidth;
                }
                // иначе
                else
                {
                    // предполагаем размещение элемента в следующей строке
                    currRowWidth = desiredWidth;
                    sumRowsHeight += gap;
 
                    // Сбрасываем высоту строки.
                    currRowHeight = 0;
                }
                // Запоминаем максимальную требуюмую ширину
                if (maxRowWidth < currRowWidth)
                    maxRowWidth = currRowWidth;
 
                // и высоту панели
                if (currRowHeight < desiredHeight)
                {
                    sumRowsHeight += -currRowHeight + desiredHeight;
                    currRowHeight = desiredHeight;
                }
            }
            maxRowWidth += gap;
            sumRowsHeight += gap;
            return new Size(maxRowWidth, sumRowsHeight);
        }
 
        // Этап размещения элементов
        protected override Size ArrangeOverride(Size finalSize)
        {
            double gap = Gap;
            double sizeWidth = finalSize.Width - gap;
            double sizeHeight = finalSize.Height - gap;
 
            var children = Children.Cast<UIElement>().ToArray(); // локальная фиксация
 
            double y = 0, nextY = 0, width = 0;
            // Коллекция, содержащая элементы текущей строки
            var row = new List<FrameworkElement>(children.Length);
            int i = 0;
            int beg = 0;
            double currRowWidth = 0;
            double offsRowY = 0;
 
            do
            {
                for (; i < children.Length && currRowWidth <= sizeWidth; i++)
                {
                    currRowWidth += children[i].DesiredSize.Width + gap;
                }
                if (beg + 1 < i && currRowWidth > sizeWidth)
                {
                    i--;
                    currRowWidth -= children[i].DesiredSize.Width + gap;
                }
 
                double currRowHeight = 0;
                for (int j = 0; j < i; j++)
                {
                    var child = children[beg];
                    Size childSize = child.DesiredSize;
                    if (currRowHeight < childSize.Height)
                        currRowHeight = childSize.Height;
                }
 
                double delta = (sizeWidth - currRowWidth) / (i - beg);
                //delta -= gap;
 
                //double maxHeight = 0;
                currRowWidth = 0;
                for (; beg < i; beg++)
                {
                    var child = children[beg];
                    Size childSize = child.DesiredSize;
 
                    double newWidth = childSize.Width + delta;
 
                    currRowWidth += gap;
                    child.Arrange(new Rect(
                        currRowWidth,
                        offsRowY,
                        newWidth,
                        currRowHeight));
                    currRowWidth += newWidth;
                }
                offsRowY += gap + currRowHeight;
                currRowWidth = 0;
            } while (i < children.Length);
 
            return finalSize;
        }
 
        private void ArrangeLine(List<FrameworkElement> line, double lineWidth, double y, double lineHeight, double gap)
        {
            //double gap = Gap;
 
            // Потребная ширина строки
            double width = line.Sum(fe => fe.DesiredSize.Width);
            // Делим оставшуюся часть длины строки на все элементы
            double delta = (lineWidth - width) / line.Count;
            // Смещение элемента внутри строки
            double x = gap;
            foreach (var fe in line)
            {
                // Вычисляем ширину текущего элемента
                double temp_curWidth = fe.DesiredSize.Width + delta;
                double curWidth = temp_curWidth - gap;
                // Размещаем элемент
                fe.Arrange(new Rect(x, y, curWidth - gap, lineHeight - gap));
                // Вычисляем смещение следующего
                x += temp_curWidth;
            }
        }
    }
}
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
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
<Window x:Class="Core2023.Topics.xellan24rus.FillingPanelArrange.FillingPanelWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Core2023.Topics.xellan24rus.FillingPanelArrange"
        xmlns:sys="clr-namespace:System;assembly=netstandard"
        mc:Ignorable="d"
        Title="FillingPanelWindow" Height="450" Width="1800">
    <Window.Resources>
        <Style TargetType="ContentControl">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate DataType="sys:String">
                        <Border Height="100" CornerRadius="6" MinWidth="350" Background="{Binding}">
                            <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">
                                <Run Text="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/>
                                <LineBreak/>
                                <Run Text="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}"/>
                                <LineBreak/>
                                <Run Text="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Border}}}"/>
                                <LineBreak/>
                                <Run Text="{Binding ActualHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Border}}}"/>
                            </TextBlock>
                        </Border>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid Margin="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Border Margin="14 20 14 0" CornerRadius="6" Height="40" Background="Gray">
            <TextBlock Margin="20 0 0 0" FontSize="20" VerticalAlignment="Center">Title</TextBlock>
        </Border>
        <local:FillingPanel Background="#F1F1F1F1" Grid.Row="1" Margin="0 14 0 0"
                                Gap="17">
            <ContentControl Content="#F1E69B9B"></ContentControl>
            <ContentControl Content="#F1653232"></ContentControl>
            <ContentControl Content="#F1421D1D"></ContentControl>
            <ContentControl Content="#F1FF2222"></ContentControl>
            <ContentControl x:Name="five" Content="#F10D004E"></ContentControl>
            <ContentControl Content="#F15135DE"></ContentControl>
            <ContentControl Content="#F1E69B9B"></ContentControl>
            <ContentControl Content="#F1653232"></ContentControl>
            <ContentControl Content="#F1421D1D"></ContentControl>
            <ContentControl x:Name="ten" Content="#F1FF2222"></ContentControl>
            <ContentControl Content="#F10D004E"></ContentControl>
            <ContentControl Content="#F15135DE"></ContentControl>
            <ContentControl Content="#F1E69B9B"></ContentControl>
            <ContentControl Content="#F1653232"></ContentControl>
        </local:FillingPanel>
    </Grid>
</Window>
Добавлено через 1 минуту
Метод ArrangeLine - не нужен.
Забыл удалить.
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
07.10.2023, 21:42  [ТС]
Элд Хасп, спасибо огромное, вы маг в wpf) Работает как часики теперь)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
09.10.2023, 09:48
xellan24rus, имейте ввиду, что ArrangeOverride неверно возвращает размер. Должен возвращать размер реально занятый элементом.
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
09.10.2023, 10:03  [ТС]
Элд Хасп, я применил эту панель для проекта, в нем у меня разместилось все ровно, равные размеры и отступы. Единственное это то что строка делит на количество элементов по ширине и то есть если разные элементы, разной ширины то и адаптация будет такая же., разной ширины элементы в строке. Но это уже можно исправить позже. То есть в панели все должно быть одинакового размера, чтобы получить на выходе одинаковые размеры. В будущем думаю исправлю. Как вариант хранить размеры элементов в первой строке и их применять для следующих строк, тогда получится авто
выравнивание если где то убежал 1-2 пикселя.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
09.10.2023, 12:34
Цитата Сообщение от xellan24rus Посмотреть сообщение
То есть в панели все должно быть одинакового размера, чтобы получить на выходе одинаковые размеры.

Я же за это спрашивал.

Тогда надо менять расчёт длины строки.
Надо не суммированием его определять, а по формуле rowCount * (maxWidth + gap).
В цикле для очередного элемента определяете его ширину, если она больше maxWidth, то временно заменяете и считаете с таким размером.
Если меньше, то с текущим maxWidth.
0
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
09.10.2023, 16:31  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я же за это спрашивал.
Я похоже нет понял, я думал вы про результат почему то.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
rowCount * (maxWidth + gap).
Количество строк * (maxWidth + gap) только не пойму как рассчитать максимальный размер элемента для строки. То есть если размер строки 715, то чтобы поместилось два элемента на всю доступную ширину строки
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
09.10.2023, 17:56
Цитата Сообщение от xellan24rus Посмотреть сообщение
только не пойму как рассчитать максимальный размер элемента для строки
Условно для одной строки:
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
int i = 0; // На уровне общего цикла по всем элементам
 
// На уровне формирования строки
    double maxRowItemWidth = 0;
    double maxRowItemHeight = 0;
    for(int beg=i; i < children.Length; i++)
    {
        var child = children[i];
        Size childSize = child.DesiredSize;
 
        double maxW = childSize.Width > maxRowItemWidth
                  ? childSize.Width
                  : maxRowItemWidth;
 
        double maxH = childSize.Height > maxRowItemHeight
                  ? childSize.Height
                  : maxRowItemHeight;
 
        double rowWidth = (i+1-beg)*(maxW+gap)
        if(beg != i || rowWidth > areaWidth)
        {
            // Откатить последний элемент и запомнить параметры строки
            i--;
           break;
        }
        else
        {
           // Запоминаем промежуточные результаты и продолжаем перебор
           maxRowItemWidth = maxW;
           maxRowItemHeight = maxH;
        }
    }
 
// Обработка параметров полученной строки
    double rowWidth = (i+1-beg)*(maxRowItemWidth+gap);
    maxRowWidth = maxRowWidth < rowWidth
          ? rowWidth : maxRowWidth;
    sumRowsHeight += maxRowItemHeight + gap;
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
09.10.2023, 19:03  [ТС]
Элд Хасп, спасибо) Поклацав понял что надо добавлять dp свойство для указания минимального размера. Так как если я в wpf указываю MinWidth, то я могу настроить сколько на начальном размере элементов будет в строке с заданным отступом, а если укажу Width, то я не смогу менять размер с панели для фиксированного элемента. Так как я часто использую Border, то в пример был тоже он стилем для панели я задавал минимальный размер что привело к потере размера у Border который в таблице содержал Border и тем самым строка стала кривой.
0
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
01.11.2023, 16:31  [ТС]
Элд Хасп, можете пожалуйста подсказать с панелью ещё раз.
Не могу понять как настроить высоту строки по максимальной высоте элемента в строке

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

Код c#
Кликните здесь для просмотра всего текста
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
namespace Wpap_Test
{
    public class FillingPanel : Panel
    {
        /// <summary>Зазар между ячейками.</summary>
        public double Gap
        {
            get { return (double)GetValue(GapProperty); }
            set { SetValue(GapProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Gap.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GapProperty =
            DependencyProperty.Register(nameof(Gap), typeof(double), typeof(FillingPanel), new FrameworkPropertyMetadata(0d) { AffectsArrange = true });
 
        public double MinWidthElement
        {
            get { return (double)GetValue(MinWidthElementProperty); }
            set { SetValue(MinWidthElementProperty, value); }
        }
 
        public static readonly DependencyProperty MinWidthElementProperty =
            DependencyProperty.Register(nameof(MinWidthElement), typeof(double), typeof(FillingPanel), new FrameworkPropertyMetadata(0d) { AffectsArrange = true });
 
 
        // Этап подсчета занимаемого места
        protected override Size MeasureOverride(Size availableSize)
        {
            // Фиксация зазора
            double gap = Gap;
            double minWidth = MinWidthElement;
            // Ширина-Высота и размер клиентской обюласти за вычетом зазоров по краям.
            double sizeWidth = availableSize.Width - gap - gap;
            double sizeHeight = availableSize.Height - gap - gap;
            Size contentSize = new Size(sizeWidth, sizeHeight);
 
            double currRowWidth = 0;
            double maxRowWidth = 0;
            double currRowHeight = 0;
            double sumRowsHeight = 0;
            double desiredWidth = 0;
            double rowWidth = sizeWidth + gap; // Размер строки включая один зазор.
            foreach (FrameworkElement child in Children)
            {
                // Запрашиваем измерение желаемого размера
                child.Measure(contentSize);
                Size desiredSize = child.DesiredSize;
                if(minWidth > desiredSize.Width)
                desiredWidth = minWidth + gap;
                else 
                    desiredWidth = desiredSize.Width + gap;
                double desiredHeight = desiredSize.Height;
 
                // Если элемент первый или помещается в текущую строку
                if (currRowWidth == 0 || currRowWidth + desiredWidth <= rowWidth)
                {
                    // увеличиваем ширину текущей строки
                    currRowWidth += desiredWidth;
                }
                // иначе
                else
                {
                    // предполагаем размещение элемента в следующей строке
                    currRowWidth = desiredWidth;
                    sumRowsHeight += gap;
 
                    // Сбрасываем высоту строки.
                    currRowHeight = 0;
                }
                // Запоминаем максимальную требуюмую ширину
                if (maxRowWidth < currRowWidth)
                    maxRowWidth = currRowWidth;
 
                // и высоту панели
                if (currRowHeight < desiredHeight)
                {
                    sumRowsHeight += -currRowHeight + desiredHeight;
                    currRowHeight = desiredHeight;
                }
 
            }
            maxRowWidth += gap;
            sumRowsHeight += gap;
            return new Size(maxRowWidth, sumRowsHeight);
        }
 
        // Этап размещения элементов
        protected override Size ArrangeOverride(Size finalSize)
        {
            double gap = Gap;
            double minWidth = MinWidthElement;
            double maxWidth_Element = 0;
            double sizeWidth = finalSize.Width - gap;
 
            var children = Children.Cast<UIElement>().ToArray(); // локальная фиксация
            int i = 0;
            int rowCount = 0;
            int beg = 0;
            double currRowWidth = 0;
            double offsRowY = 0;
 
            while (i < children.Length) 
            {
                for (; i < children.Length && currRowWidth <= sizeWidth; i++)
                {
                    if(minWidth > children[i].DesiredSize.Width)
                        currRowWidth += minWidth + gap;
                    else
                        currRowWidth += children[i].DesiredSize.Width + gap;
                    rowCount++;
                }
                if (beg + 1 < i && currRowWidth > sizeWidth)
                {
                    i--;
                    rowCount--;
                    if (minWidth > children[i].DesiredSize.Width)
                        currRowWidth -= minWidth;
                    else
                    currRowWidth -= children[i].DesiredSize.Width + gap;
                }
 
                double currRowHeight = 0;
                for (int j = 0; j < i; j++)
                {
                    var child = children[beg];
                    Size childSize = child.DesiredSize;
                    if (currRowHeight < childSize.Height)
                        currRowHeight = childSize.Height;
                }
                double newWidth = (sizeWidth / rowCount) - gap;
                if (maxWidth_Element == 0)
                    maxWidth_Element = newWidth;
                else
                    newWidth = maxWidth_Element;
                double offsetX = 0.0;
                for (; beg < i; beg++)
                {
                    var child = children[beg];
                    offsetX += gap;
                    child.Arrange(new Rect(
                        offsetX,
                        offsRowY,
                        newWidth,
                        currRowHeight));
                    offsetX += newWidth;
                }
                offsRowY += gap + currRowHeight;
                currRowWidth = 0;
                rowCount = 0;
            } 
 
            return finalSize;
        }
    }
}


Wpf

Кликните здесь для просмотра всего текста
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
34
35
36
37
38
39
40
41
42
43
<Window x:Class="Wpap_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpap_Test"
        mc:Ignorable="d"
        Title="MainWindow" Height="1000" Width="741" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid Margin="0">
            <Grid.RowDefinitions>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
            <Border Margin="14 20 14 0" CornerRadius="6" Height="40" Background="Gray">
                <TextBlock Margin="20 0 0 0" FontSize="20" VerticalAlignment="Center">Title</TextBlock>
            </Border>
            <local:FillingPanel  Background="#F1D2AAAA" Margin="0 14 0 0" Grid.Row="1" Gap="14" MinWidthElement="320" >
                <local:FillingPanel.Resources>
                    <Style TargetType="Border">
                        <Setter Property="Background" Value="#FF133EC3"></Setter>
                        <Setter Property="CornerRadius" Value="6"></Setter>
                    </Style>
                </local:FillingPanel.Resources>
                <Border Name="r" Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="99" Padding="0 0 0 14"></Border>
                <Border Height="150"  Padding="0 0 0 14"></Border>
                <Border Height="150" Padding="0 0 0 14"></Border>
                <Border VerticalAlignment="Top" Height="79" Padding="0 0 0 14"></Border>
                <Border VerticalAlignment="Top"  Height="79" Padding="0 0 0 14"></Border>
                <Border Height="160" Padding="0 0 0 14"></Border>
                <Border  VerticalAlignment="Top" Height="79" Padding="0 0 0 14"></Border>
            </local:FillingPanel>
        </Grid>
    </Grid>
</Window>
0
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
01.11.2023, 18:53  [ТС]
Код который принимает высоту строки по максимальному размеру элемента в строке
Кликните здесь для просмотра всего текста
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
 
namespace Wpap_Test
{
    public class FillingPanel : Panel
    {
        /// <summary>Зазар между ячейками.</summary>
        public double Gap
        {
            get { return (double)GetValue(GapProperty); }
            set { SetValue(GapProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Gap.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GapProperty =
            DependencyProperty.Register(nameof(Gap), typeof(double), typeof(FillingPanel), new FrameworkPropertyMetadata(0d) { AffectsArrange = true });
 
        public double MinWidthElement
        {
            get { return (double)GetValue(MinWidthElementProperty); }
            set { SetValue(MinWidthElementProperty, value); }
        }
 
        public static readonly DependencyProperty MinWidthElementProperty =
            DependencyProperty.Register(nameof(MinWidthElement), typeof(double), typeof(FillingPanel), new FrameworkPropertyMetadata(0d) { AffectsArrange = true });
 
 
        // Этап подсчета занимаемого места
        protected override Size MeasureOverride(Size availableSize)
        {
            // Фиксация зазора
            double gap = Gap;
            double minWidth = MinWidthElement;
            // Ширина-Высота и размер клиентской обюласти за вычетом зазоров по краям.
            double sizeWidth = availableSize.Width - gap - gap;
            double sizeHeight = availableSize.Height - gap - gap;
            Size contentSize = new Size(sizeWidth, sizeHeight);
 
            double currRowWidth = 0;
            double maxRowWidth = 0;
            double currRowHeight = 0;
            double sumRowsHeight = 0;
            double desiredWidth = 0;
            double rowWidth = sizeWidth + gap; // Размер строки включая один зазор.
            foreach (FrameworkElement child in Children)
            {
                // Запрашиваем измерение желаемого размера
                child.Measure(contentSize);
                Size desiredSize = child.DesiredSize;
                if(minWidth > desiredSize.Width)
                desiredWidth = minWidth + gap;
                else 
                    desiredWidth = desiredSize.Width + gap;
                double desiredHeight = desiredSize.Height;
 
                // Если элемент первый или помещается в текущую строку
                if (currRowWidth == 0 || currRowWidth + desiredWidth <= rowWidth)
                {
                    // увеличиваем ширину текущей строки
                    currRowWidth += desiredWidth;
                }
                // иначе
                else
                {
                    // предполагаем размещение элемента в следующей строке
                    currRowWidth = desiredWidth;
                    sumRowsHeight += gap;
 
                    // Сбрасываем высоту строки.
                    currRowHeight = 0;
                }
                // Запоминаем максимальную требуюмую ширину
                if (maxRowWidth < currRowWidth)
                    maxRowWidth = currRowWidth;
 
                // и высоту панели
                if (currRowHeight < desiredHeight)
                {
                    sumRowsHeight += -currRowHeight + desiredHeight;
                    currRowHeight = desiredHeight;
                }
 
            }
            maxRowWidth += gap;
            sumRowsHeight += gap;
            return new Size(maxRowWidth, sumRowsHeight);
        }
 
        // Этап размещения элементов
        protected override Size ArrangeOverride(Size finalSize)
        {
            double gap = Gap;
            double minWidth = MinWidthElement;
            double maxWidth_Element = 0;
            double sizeWidth = finalSize.Width - gap;
 
            var children = Children.Cast<UIElement>().ToArray(); // локальная фиксация
            int i = 0;
            int rowCount = 0;
            int beg = 0;
            double currRowWidth = 0;
            double offsRowY = 0;
 
            while (i < children.Length) 
            {
                for (; i < children.Length && currRowWidth <= sizeWidth; i++)
                {
                    if(minWidth > children[i].DesiredSize.Width)
                        currRowWidth += minWidth + gap;
                    else
                        currRowWidth += children[i].DesiredSize.Width + gap;
                    rowCount++;
                }
                if (beg + 1 < i && currRowWidth > sizeWidth)
                {
                    i--;
                    rowCount--;
                    if (minWidth > children[i].DesiredSize.Width)
                        currRowWidth -= minWidth;
                    else
                    currRowWidth -= children[i].DesiredSize.Width + gap;
                }
 
                double currRowHeight = 0;
                double newWidth = (sizeWidth / rowCount) - gap;
                if (maxWidth_Element == 0)
                    maxWidth_Element = newWidth;
                else
                    newWidth = maxWidth_Element;
                double offsetX = 0.0;
                for (; beg < i; beg++)
                {
                    var child = children[beg];
                    if(currRowHeight < child.DesiredSize.Height)
                    currRowHeight = child.DesiredSize.Height;
                    offsetX += gap;
                    child.Arrange(new Rect(
                        offsetX,
                        offsRowY,
                        newWidth,
                        currRowHeight));
                    offsetX += newWidth;
                }
                offsRowY += gap + currRowHeight;
                currRowWidth = 0;
                rowCount = 0;
            } 
 
            return finalSize;
        }
    }
}


Результат, может пригодится кому то.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
01.11.2023, 20:50
Цитата Сообщение от xellan24rus Посмотреть сообщение
можете пожалуйста подсказать с панелью ещё раз.
Вроде разобрались сами.
До конца недели буду загружен "выше крыши".
0
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
01.11.2023, 20:54  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вроде разобрались сами.
До конца недели буду загружен "выше крыши".
уже разобрался, надо было по другому думать чтобы решить вопрос. А я почему то считал иначе.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
До конца недели буду загружен "выше крыши".
Успехов в делах)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.11.2023, 20:54

Открытие файла Excel на весь экран
Как открыть файл Excel в полно экранном режиме? Открывает через раз(т.е один раз открывает на весь экран, второй раз в окне(не на весь...

Открытие приложения на весь экран - full screen mode
Кто-то спрашивал про это: Declare Function SetWindowPos Lib 'user32' (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As...

Не получается настроить открытие doc и docx файлов 2016 вордом вместо 2007 ворда
Проблема следующая: на компьютере одновременно установлены 2007 офис и 2016 офис. Необходимо, чтобы файлы doc и docx открывались вордом...

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

Запретить разворачивание окна программы на весь экран
Здравствуйте, как сделать так, чтобы программу нельзя было развернуть на весь экран? Это же делается в Desktop Launcher? Добавлено...


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

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru