Форум программистов, компьютерный форум, киберфорум
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. Показов 2036. Ответов 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
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,171
Записей в блоге: 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
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,171
Записей в блоге: 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
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,171
Записей в блоге: 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
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,171
Записей в блоге: 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
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,171
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru