Принудительное изменение размера пользовательского элемента управления WPF - PullRequest
5 голосов
/ 06 февраля 2009

Я написал пользовательский элемент управления WPF, и его часть включает в себя динамическое добавление элементов к холсту, что влияет на высоту указанного холста. Холст вложен в сетку. Когда я динамически добавляю свои элементы, высота холста изменяется, но холст в конечном итоге выходит за пределы общего элемента управления, а не заставляет его изменять размеры и становиться выше. Как я могу принудительно изменить размер элемента управления? У меня такое ощущение, что мне нужно либо вызвать, либо переопределить Measure или Arrange, но мне не везет ни с одним из методов - возможно, потому, что я вызываю их с неправильными параметрами или, возможно, потому что они не являются правильными методами для вызова.

Ответы [ 4 ]

16 голосов
/ 10 февраля 2009

Ваша проблема в том, что панели Canvas не меняются в соответствии с их содержанием.

Вы ссылались на Измерение и Аранжировка. Вы знакомы с двухпроходной системой макетов WPF? Прочтите эту статью для получения дополнительной информации: Система макетов WPF .

В этой статье также описывается, что разные панели делают для макета. Каждый тип панели отличается.

В WPF элементам сначала предоставляется возможность определить, какого размера они будут. Группы могут определять свой размер в зависимости от размера своих детей, или они могут запрашивать фиксированный размер независимо от размера своих детей. Холст является примером последнего.

Затем элементам сообщают, какого они размера, и просят договориться о себе и своих детях.

Тип панели «Сетка» не только допускает строки и столбцы, но также очень хорош при автоматическом изменении размера содержимого.

Тип StackPanel не имеет автоматического размера в измерении, в котором он ориентирован, но он будет автоматически изменяться в другом измерении.

Canvas может автоматически изменять размер, чтобы заполнить пробел, но он никогда не позволяет дочерним элементам автоматически изменять размер. Он рисует своих детей в указанных координатах и ​​не заботится о том, насколько они велики.

Я бы предложил попробовать Сетка только с одной строкой / столбцом.

Или вы можете создать новый класс Canvas с улучшенными возможностями автоматического изменения размера. Во время измерения вы хотели бы измерить дочерние элементы и соответственно изменить размер вашего холста. Вы могли бы найти класс, как это полезно в будущем.

Вот статья о Auto Layout в WPF.

Если вы хотите создать пользовательскую панель, здесь есть подтема: Элементы пользовательской панели .

EDIT: Еще одна вещь: вы также можете привязать ширину / высоту дочернего элемента к свойствам ActualWidth и ActualHeight на холсте, чтобы дочерний элемент регулировал размер его родителя. При необходимости вы можете использовать конвертер для установки соотношения размеров.

2 голосов
/ 09 августа 2011

Вы пытались обернуть все (содержимое пользовательского элемента управления) в Viewbox? например,

 <UserControl>
    <Border BorderBrush="Black" BorderThickness="1">
        <Viewbox>
            <Grid>
                <TextBlock Name="txtDefault" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" Foreground="Black" Opacity="0.5" Text="Default" />
                <TextBlock Name="txtValue" FontSize="16" Foreground="Black" Visibility="Collapsed" />
                <TextBlock Name="txtKey" Grid.Column="1" FontSize="18" Foreground="Black" Visibility="Collapsed" />
            </Grid>
        </Viewbox>
    </Border>
</UserControl>
1 голос
/ 09 февраля 2009

Вам необходимо переопределить метод MeasureOverride вашего элемента управления и вернуть оттуда желаемый размер (размер вашего холста). Тогда родительский элемент управления изменит свой размер, чтобы приспособить его дочерний элемент (если может).

0 голосов
/ 23 июля 2009

Вы можете использовать UniFormGrid для архивирования. Установите Столбцы или Строку равными 1, чтобы вы могли получить расположенные вертикально или горизонтально элементы

<UniformGrid  Columns="1">
   <Button Content="Content 1"/>
   <Button Content="Content 2"/>
   <Button Content="Content 3"/>
</UniformGrid>
...