Первый дочерний элемент WPF Dockpanel использует оставшееся пространство

В окошке у меня есть список DockPanel для указания пары файлов. Каждая DockPanel имеет текстовое поле (для пути) и кнопку (для поиска файла).

Я воссоздал простую страницу WPF, чтобы продемонстрировать проблему здесь:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="150"
    Height="22">
    <DockPanel>
        <TextBox HorizontalAlignment="Stretch"/> <!-- path to file -->
        <Button Content="..." DockPanel.Dock="Right"/> <!-- button to browse for file -->
    </DockPanel>
</Page>

Проблема в том, что я хочу, чтобы кнопка была справа от текстового поля, но это приводит к тому, что текстовое поле становится очень маленьким, поскольку LastChild DockPanel — это кнопка, которая использует оставшееся пространство. Я пытался изменить это, перетасовав их и установив LastChildFill="False", но это только приводит к тому, что кнопка снова становится маленькой, а не делает TextBox широким (даже с HorizontalAlignment="Stretch").

Причина, по которой мне нужны элементы управления в таком порядке, заключается в том, что я хочу, чтобы пользователь достиг TextBox перед кнопкой при использовании tab для навигации в окне. Я просмотрел настройку TabIndex, но она кажется хакерской, любимая функция WPF заключается в том, что tabindex находится в том порядке, в котором элементы управления определены в XAML. Не говоря уже о том, что мне, вероятно, придется вручную устанавливать TabIndex для всего в окне.

Мне кажется, что настройка TextBox.HorizontalAlignment не соблюдается. Как сделать так, чтобы первый элемент управления занимал как можно больше места, но при этом сохранял порядок табуляции?


person Mizipzor    schedule 09.09.2010    source источник


Ответы (2)


Если вам не нужно поведение DockPanel, не используйте DockPanel.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <TextBox />
    <Button Content="..." Grid.Column="1"/>
</Grid>
person John Bowen    schedule 09.09.2010
comment
+1, потому что у него нет проблемы с TabOrder. Если кто-то хочет избежать ввода ColumnDefinitions в таких простых сценариях, взгляните на это решение: rachel53461.wordpress.com/2011/09/17/ - person surfen; 28.03.2012

Сделайте это так:

<DockPanel LastChildFill="True">
    <Button Content="..." DockPanel.Dock="Right"/> <!-- button to browse for file -->
    <TextBox DockPanel.Dock="Left" HorizontalAlignment="Stretch"/> <!-- path to file -->
</DockPanel>
person Jonathan Barez    schedule 05.11.2010
comment
Великолепно! Совершенно неинтуитивно и неприятно, но работает как шарм и имеет странный смысл, учитывая, как спроектирована DockPanel. Хороший звонок. - person TonganJedi; 14.05.2011
comment
Я видел это несколько раз. Меня больше всего беспокоит то, что порядок элементов в XAML больше не соответствует визуальному расположению окна. И это портит порядок табуляции. - person Christoffer Lette; 20.10.2011
comment
Я согласен с @ChristofferLette +1, но на всякий случай, если кому-то это нужно, вот обходной путь для проблемы с табулятором. Это может быть довольно много ручной работы и не всегда хорошо работает (например, с DataGrid): stackoverflow.com/a/4808810 /724944 - person surfen; 28.03.2012
comment
Хороший! Я боролся с аналогичной проблемой и не понял, что дочерний порядок не отражает визуальный порядок, и это решило мою проблему для меня. - person Nathan Dace; 06.12.2013
comment
Сделал это в базовом контексте (одна растянутая верхняя область и одна нижняя область), и порядок табуляции был в порядке. Возможно, проблема проявляется только в определенных условиях? - person Chris; 07.03.2016