Comment configurer un contrôle TextBox pour se redimensionner automatiquement verticalement lorsque le texte ne tient plus sur une ligne?
Comment puis-je configurer un TextBox
de contrôle pour redimensionner automatiquement lui-même à la verticale lorsque le texte n'est plus adapté sur une seule ligne?
Par exemple, dans le code XAML suivant:
<DockPanel LastChildFill="True" Margin="0,0,0,0">
<Border Name="dataGridHeader"
DataContext="{Binding Descriptor.Filter}"
DockPanel.Dock="Top"
BorderThickness="1"
Style="{StaticResource ChamelionBorder}">
<Border
Padding="5"
BorderThickness="1,1,0,0"
BorderBrush="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=dc:NavigationPane,
ResourceId={x:Static dc:NavigationPaneColors.NavPaneTitleBorder}}}">
<StackPanel Orientation="Horizontal">
<TextBlock
Name="DataGridTitle"
FontSize="14"
FontWeight="Bold"
Foreground="{DynamicResource {ComponentResourceKey
TypeInTargetAssembly=dc:NavigationPane,
ResourceId={x:Static dc:NavigationPaneColors.NavPaneTitleForeground}}}"/>
<StackPanel Margin="5,0" Orientation="Horizontal"
Visibility="{Binding IsFilterEnabled, FallbackValue=Collapsed, Mode=OneWay, Converter={StaticResource BooleanToVisibility}}"
IsEnabled="{Binding IsFilterEnabled, FallbackValue=false}" >
<TextBlock />
<TextBox
Name="VerticallyExpandMe"
Padding="0, 0, 0, 0"
Margin="10,2,10,-1"
AcceptsReturn="True"
VerticalAlignment="Center"
Text="{Binding QueryString}"
Foreground="{DynamicResource {ComponentResourceKey
TypeInTargetAssembly=dc:NavigationPane,
ResourceId={x:Static dc:NavigationPaneColors.NavPaneTitleForeground}}}">
</TextBox>
</StackPanel>
</StackPanel>
</Border>
</Border>
</DockPanel>
La TextBox
contrôle nommé "VerticallyExpandMe" besoins d'étendre automatiquement à la verticale lorsque le texte lié à elle ne tient pas sur une seule ligne. Avec AcceptsReturn
définie sur true, TextBox
s'étend à la verticale si j'appuie sur entrer à l'intérieur, mais je veux faire cela automatiquement.
source d'informationauteur Klaus Nji
Vous devez vous connecter pour publier un commentaire.
Bien que André Luus la suggestion est fondamentalement correct, il ne fait pas travailler ici, parce que votre mise en page de la défaite de l'habillage de texte. Je vais vous expliquer pourquoi.
Fondamentalement, le problème est le suivant: l'habillage du texte seul ne fait rien quand un élément de la largeur est limitée, mais votre
TextBox
a sans contrainte de largeur, car c'est un descendant d'une horizontaleStackPanel
. (Eh bien, deux horizontale de la pile de panneaux. Peut-être plus, en fonction du contexte, à partir de laquelle vous avez pris votre exemple.) Étant donné que la largeur est sans contrainte, leTextBox
n'a aucune idée de quand il est censé commencer l'emballage, et donc il n'enroulez jamais, même si vous activez l'emballage. Vous devez faire deux choses: limiter sa largeur et de permettre à l'emballage.Voici une explication plus détaillée.
Votre exemple, contient beaucoup de détails non pertinents pour le problème. Voici une version que j'ai ramené un peu pour le rendre plus facile d'expliquer quel est le problème:
Donc je l'ai supprimé de votre contenant
DockPanel
et les deux imbriquésBorder
éléments à l'intérieur de cela, parce qu'ils sont ni une partie du problème, ni pertinente pour la solution. Donc, je suis au départ de la paire de imbriquéeStackPanel
éléments dans votre exemple. Et j'ai aussi supprimé la plupart des attributs, car la plupart d'entre eux sont également pertinents pour la mise en page.Cela semble un peu bizarre d'avoir deux imbriqués horizontale de la pile de panneaux comme cela semble redondant, mais il n'a réellement de sens que dans l'original de votre si vous avez besoin de faire le imbriqués l'un visible ou invisible au moment de l'exécution. Mais il est plus facile de voir le problème.
(Le vide
TextBlock
tag est aussi bizarre, mais c'est exactement comme il apparaît dans le document d'origine. Qui ne semble pas être quelque chose d'utile.)Et voici le problème: votre
TextBox
est à l'intérieur de certaines horizontaleStackPanel
éléments, à savoir sa largeur est sans contrainte - vous, par inadvertance, a dit la zone de texte qu'il est libre de se développer à n'importe quelle largeur, quel que soit l'espace réellement disponible.Un
StackPanel
sera toujours effectuer une mise en page qui est sans contrainte dans la direction de l'empilement. Alors, quand il s'agit de laïcs queTextBox
ça va passer à une taille horizontale de l'double.PositiveInfinity
à laTextBox
. Ainsi, leTextBox
toujours pense qu'il y a plus d'espace que nécessaire. En outre, lorsqu'un enfantStackPanel
demande plus d'espace que ce qui est réellement disponible, leStackPanel
mensonges, et fait semblant de lui donner autant de place, mais ensuite cultures.(C'est le prix à payer pour l'extrême simplicité de
StackPanel
- c'est simple, au point d'être des os de la tête, car il se fera un plaisir de construire des mises en page qui ne répondent pas vraiment. Vous devez uniquement utiliserStackPanel
si tu as vraiment de l'espace illimité parce que vous êtes à l'intérieur d'unScrollViewer
ou que vous êtes certain que vous avez suffisamment de quelques articles que vous n'allez pas manquer d'espace, ou si vous n'avez pas de soins sur les éléments en cours d'exécution hors de l'extrémité du panneau quand ils deviennent trop grands et que vous ne voulez pas que le système de mise en page pour essayer de faire quelque chose de plus intelligent que de simplement recadrer le contenu.)Donc tourner sur habillage du texte ne va pas aider ici, parce que le
StackPanel
toujours prétendre qu'il n'y a plus assez d'espace pour le texte.Vous avez besoin d'une mise en page différente de la structure. Pile de panneaux n'est pas la bonne chose à utiliser, car ils ne seront pas imposer la contrainte de mise en page vous avez besoin pour obtenir de l'habillage de texte à coup de pied dans.
Voici un exemple simple qui fait à peu près ce que vous voulez:
Si vous créez une image de marque nouvelle application WPF et le coller dans le contenu de la fenêtre principale, vous devriez trouver qu'il fait ce que vous voulez - le
TextBox
commence une ligne de hauteur, le remplit de la largeur disponible, et si vous tapez du texte, il va pousser une ligne à la fois que vous ajoutez plus de texte.Bien sûr, la mise en page de comportement est toujours sensible au contexte, de sorte qu'il peut ne pas être suffisant de simplement jeter que dans le milieu de votre application existante. Qui va travailler si collé dans une taille fixe de l'espace (par exemple, comme le corps d'une fenêtre), mais ne fonctionnera pas correctement si vous le collez dans un contexte où la largeur est sans contrainte. (E. g., à l'intérieur d'un
ScrollViewer
ou à l'intérieur d'une horizontaleStackPanel
.)Donc, si cela ne fonctionne pas pour vous, ce sera parce que d'autres choses de mal, d'ailleurs dans votre mise en page - peut-être encore plus
StackPanel
éléments ailleurs. De l'apparence de votre exemple, c'est probablement la peine de passer quelques temps à penser à ce que vous avez vraiment besoin dans votre mise en page et de simplification - la présence de marges négatives, et les éléments qui n'apparaissent pas à faire quoi que ce soit videTextBlock
sont généralement indicatif d'une présentation compliquée. Et la complexité d'une mise en page rend plus difficile d'obtenir les effets que vous recherchez.Sinon, vous pouvez contraindre votre
TextBlock
'sWidth
en le liant à un parentActualWidth
par exemple:Cela va l'obliger à redimensionner la hauteur automatiquement.
Utilisation
MaxWidth
etTextWrapping="WrapWithOverflow"
.Je suis en utilisant une autre approche simple qui me permet de ne pas modifier la mise en page du document.
L'idée principale est de ne pas définir le contrôle
Width
avant qu'il ne commence à changer. PourTextBox
es, j'ai la poignée de laSizeChanged
événement:Vous pouvez utiliser cette classe qui s'étend TextBlock. Il ne auto-réduction et prend MaxHeight /MaxWidth en considération: