powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Layout Expander with DataGrid
7 сообщений из 7, страница 1 из 1
Layout Expander with DataGrid
    #39863565
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
эксперты, подскажите новичку, как это делается в WPF.
Делаю следующий layout.

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
<DockPanel>
  <Expander DockPanel.Dock="Top" IsExpanded="True">
    <Expander.Header>
      <TextBlock>Files1</TextBlock>
    </Expander.Header>
    <DataGrid ItemsSource="{Binding Path=FoundFiles1, Mode=OneWay}">
  </DataGrid>
</Expander>
  <Expander DockPanel.Dock="Top" IsExpanded="True">
    <Expander.Header>
      <TextBlock>Files2</TextBlock>
    </Expander.Header>
    <DataGrid ItemsSource="{Binding Path=FoundFiles2, Mode=OneWay}">
  </DataGrid>
</Expander>
</DockPanel>



Модератор: Учимся использовать тэги оформления кода - FAQ

не получается добиться желаемого поведения.

Хочу чтобы заголовки Expander-ов были всегда видимы. Если один Expander открыт то DataGrid занимал Min(Required, Available) пространства. Здесь available - всё допустимое пространство минус заголовки.
Если оба Expander-а открыты то в зависимости от того,
если Sum(DataGrid1.Required + DataGrid2.Required) < Available -> Как в StackPanel
(другими словами каждый DataGrid размером с Required)
в противном случае каждый DataGrid размером с Min(Required, Available / 2)

Незнаю как проще описать желаемый результат, но может кто подскажет.
Принцип в принципе простой: заполнить все возможное пространство с максимум информации и в тоже время Expander всегда видим.
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39863578
Roman Mejtes
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron,
HeaderedContentControl

2 часть вопроса требует уточнения, нужны нормальные формулировки.
Контрол судя по описанию напоминает элемент управления аккордеон.
Имеет смысл создать отдельный контрол на базе ItemsControl'а, в который будет укладываться Expander'ы. Можно даже переопределить метод конструктор для генератора. Он будет возвращать сразу тот элемент, что нам нужно. Шаблон элемента можно передать через TemplateBinding. А заголовок оставить либо всегда текстовым, либо добавлять свойства зависимости для шаблона заголовка, вроде в ItemsControl этого нет.
Элементы управления в ItemsControl можно размещать на любую панель, даже "собственного производства"
Мин размер задать размер заголовка, вообще можно кидать даже в панель Grid и менять у строк\колонок отношение сторон, если не нужен скроллинг в этой области.
может я не то понял, тогда сорян
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39863584
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Навскидку.
Расположить экспандеры в гриде, высота первой строки - авто, второй - звездочка.
Привязать байндингом MaxHeight первого экспандера к половине высоты общего контейнера, но привязка с условием, что второй экспандер развернут.
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39863688
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

Почти так.
Если 2й развёрнут но его размер меньше половины то MaxHeight первого экспандера больше чем половина, точнее вся свободная область.
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39863701
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хм. Может тогда проще будет нафигачить свою панель, кода будет мало, но можно реализовать хотелки. Панель сделать не так сложно, как кажется
WPF: Шпаргалка для создания панели
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39863875
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

Буду так делать, спасибо.
...
Рейтинг: 0 / 0
Layout Expander with DataGrid
    #39871153
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот что пока настрогал.
Если кому пригодится - берите.


Код: 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.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfCustomContainer
{
    public class ConstraintStackPanel : StackPanel
    {
        internal List<GridLength> _gridLengths;
        internal GridLengthConstraintCollection _gridConstraintCollection;

        public GridLengthConstraintCollection GridConstraints
        {
            get
            {
                if (_gridConstraintCollection == null)
                {
                    _gridLengths = new List<GridLength>();
                    _gridConstraintCollection = new GridLengthConstraintCollection(this);
                }
                return _gridConstraintCollection;
            }
        }

        public ConstraintStackPanel()
        { 
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            var desiredSize = new Size();
            var vertical = this.Orientation == Orientation.Vertical;
            var postponedIndex = new List<int>();
            double totalStars = 0.0;
            int index = 0;
            foreach (UIElement element in this.InternalChildren)
            {
                var gl = _gridLengths != null && index < _gridLengths.Count ? _gridLengths[index] : GridLength.Auto;
                if (gl.IsStar)
                {
                    postponedIndex.Add(index++);
                    totalStars += gl.Value;
                    continue;
                }
                Size constraint;
                if (gl.IsAuto)
                {
                    constraint = vertical
                        ? new Size(availableSize.Width, double.PositiveInfinity)
                        : new Size(double.PositiveInfinity, availableSize.Height);
                }
                else
                {
                    constraint = vertical
                        ? new Size(availableSize.Width, gl.Value)
                        : new Size(gl.Value, availableSize.Height);
                }
                element.Measure(constraint);
                var size = element.DesiredSize;
                if (vertical)
                {
                    desiredSize.Width = Math.Max(desiredSize.Width, size.Width);
                    desiredSize.Height += size.Height;
                }
                else
                {
                    desiredSize.Width += size.Width;
                    desiredSize.Height = Math.Max(desiredSize.Height, size.Height);
                }
                index +=1;
            }
            // Measure stared elements
            var readjust = true;
            while (readjust)
            {
                readjust = false;
                for (index = postponedIndex.Count; --index >= 0;)
                {
                    var element = this.InternalChildren[postponedIndex[index]];
                    var g = _gridLengths[postponedIndex[index]].Value;

                    var constraint = vertical
                        ? new Size(availableSize.Width, g * (availableSize.Height - desiredSize.Height) / totalStars)
                        : new Size(g * (availableSize.Width - desiredSize.Width) / totalStars, availableSize.Height);
                    if (constraint.Width <= 0.0 || constraint.Height <= 0)
                        break;
                    element.Measure(constraint);
                    var size = element.DesiredSize;
                    if (vertical && size.Height < constraint.Height)
                    {
                        desiredSize.Width = Math.Max(desiredSize.Width, size.Width);
                        desiredSize.Height += size.Height;
                        totalStars -= g;
                        postponedIndex.RemoveAt(index);
                        readjust = true;
                    }
                    else if (!vertical && size.Width < constraint.Width)
                    {
                        desiredSize.Width += size.Width;
                        desiredSize.Height = Math.Max(desiredSize.Height, size.Height);
                        totalStars -= g;
                        postponedIndex.RemoveAt(index);
                        readjust = true;
                    }
                }
            }
            if (index >= 0)
            {
                // finally just allow remaining stared elements to take whole place
                foreach (var idx in postponedIndex)
                {
                    var element = this.InternalChildren[idx];
                    var constraint = vertical
                            ? new Size(availableSize.Width, double.PositiveInfinity)
                            : new Size(double.PositiveInfinity, availableSize.Height);
                    element.Measure(constraint);
                    var size = element.DesiredSize;
                    if (vertical)
                    {
                        desiredSize.Width = Math.Max(desiredSize.Width, size.Width);
                        desiredSize.Height += size.Height;
                    }
                    else
                    {
                        desiredSize.Width += size.Width;
                        desiredSize.Height = Math.Max(desiredSize.Height, size.Height);
                    }
                }
            }
            return desiredSize;
        }
    }

    public class GridLengthConstraintCollection : IList<GridLength>, ICollection<GridLength>, IEnumerable<GridLength>, IEnumerable, IList, ICollection
    {
        ConstraintStackPanel _panel;

        internal GridLengthConstraintCollection(ConstraintStackPanel panel)
        {
            _panel = panel;
        }

        public GridLength this[int index] { get => _panel._gridLengths[index]; set => _panel._gridLengths[index] = value; }
        object IList.this[int index] { get => ((IList)_panel._gridLengths)[index]; set => ((IList) _panel._gridLengths)[index] = value; }

        public int Count => _panel._gridLengths.Count;

        public bool IsReadOnly => false;

        public bool IsFixedSize => false;

        public object SyncRoot => _panel._gridLengths;

        public bool IsSynchronized => false;

        public void Add(GridLength item)
        {
            _panel._gridLengths.Add(item);
        }

        public int Add(object value) => ((IList) _panel._gridLengths).Add(value);

        public void Clear()
        {
            _panel._gridLengths.Clear();
        }

        public bool Contains(GridLength item) => _panel._gridLengths.Contains(item);

        public bool Contains(object value) => ((IList) _panel._gridLengths).Contains(value);

        public void CopyTo(GridLength[] array, int arrayIndex) => _panel._gridLengths.CopyTo(array, arrayIndex);

        public void CopyTo(Array array, int index)
        {
            ((IList) _panel._gridLengths).CopyTo(array, index);
        }

        public IEnumerator<GridLength> GetEnumerator() => _panel._gridLengths.GetEnumerator();

        public int IndexOf(GridLength item) => _panel._gridLengths.IndexOf(item);

        public int IndexOf(object value) => ((IList) _panel._gridLengths).IndexOf(value);

        public void Insert(int index, GridLength item)
        {
            _panel._gridLengths.Insert(index, item);
        }

        public void Insert(int index, object value)
        {
            ((IList) _panel._gridLengths).Insert(index, value);
        }

        public bool Remove(GridLength item) => _panel._gridLengths.Remove(item);

        public void Remove(object value)
        {
            ((IList) _panel._gridLengths).Remove(value);
        }

        public void RemoveAt(int index)
        {
            _panel._gridLengths.RemoveAt(index);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable) _panel._gridLengths).GetEnumerator();
        }
    }
}


...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Layout Expander with DataGrid
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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