2017-09-25 8 views
0

Ici, j'ai la fenêtre simple:WPF Comment faire pour que la largeur RichTextBox suive celle du contrôle parent?

enter image description here

La partie supérieure est un DataGrid, ci-dessous est une zone de texte. La fenêtre est définie sur la taille du contenu. C'est la disposition souhaitée.

Maintenant, j'ai besoin d'afficher du texte enrichi, donc je remplace le TextBox par RichTextBox. Le problème est que maintenant la fenêtre étend à la largeur de l'écran, comme si (je l'ai rétréci, bien sûr, mais vous voyez l'idée):

enter image description here

J'ai essayé lier les années RichTextBox largeur à la largeur réelle du parent:

<RichTextBox Width="{Binding ElementName=Wrapper, Path=ActualWidth}"/> 

mais il s'étend toujours à la fenêtre entière. BTW la même chose arrive si j'utilise TextBox dans le code ci-dessus.

Comment puis-je adapter la largeur de la RichTextBox au parent tout en conservant la disposition dynamique des fenêtres? Je veux dire que le DataGrid est l'élément clé auquel la largeur de la fenêtre et la largeur de la RichTextBox doivent être soumises.

Vous trouverez ci-dessous le code complet.

XAML

<Window x:Class="RichTextBox_Wrap.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:RichTextBox_Wrap" 
     mc:Ignorable="d" 
     SizeToContent="Width" 
     Title="MainWindow" Height="250" > 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="30"/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 
     <DataGrid Grid.Row="0" 
        HeadersVisibility="Column" 
        CanUserAddRows="False" 
        ItemsSource="{Binding Items}"> 
     </DataGrid> 
     <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"> 
      <TextBlock Text="Info" /> 
     </StackPanel> 
     <DockPanel x:Name="Wrapper" Grid.Row="2"> 
      <Border BorderBrush="CadetBlue" BorderThickness="1"> 
       <RichTextBox /> 
      </Border> 
     </DockPanel> 
    </Grid> 
</Window> 

C#

public class Item 
    { 
     public string Name { get; set; } 
     public string Description { get; set; } 
     public double Price { get; set; } 
    } 

    public class ViewModel 
    { 
     public ObservableCollection<Item> Items { get; set; } 

     public ViewModel() 
     { 
      Items = new ObservableCollection<Item> 
      { 
       new Item {Name = "Apple", Description="Fruit", Price=3}, 
       new Item {Name = "Banana", Description="Fruit", Price=5}, 
       new Item {Name = "Tomato", Description="Vegetable", Price=4}, 
      }; 
     } 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new ViewModel(); 
     } 
    } 

SOLUTIONS

1. solution presque œuvres de MM8, mais il semble que l'événement Loaded arrive tôt pour calculer le ActualWidth correctement - RichTextBox ne remplit pas le wid th et laisse des lacunes. Mais en prenant l'idée plus loin, j'ai utilisé l'événement "Content_Rendered" de la fenêtre pour fixer la largeur de la fenêtre, puis définir la largeur de RichTextBox sur auto.

<RichTextBox x:Name="RichBox" Grid.Row="1" MinHeight="75" Width="0" Visibility="Hidden" /> 

private void Window_ContentRendered(object sender, EventArgs e) 
{ 
    var window = sender as Window; 
    window.SizeToContent = SizeToContent.Manual; 
    window.Width = window.ActualWidth; 
    RichBox.Width = double.NaN; 
    RichBox.Visibility = Visibility.Visible; 
} 

2. Spongebrot était sur place. En effet, lorsque la bordure supplémentaire est supprimée, la liaison à la fonction ActualWidth du parent est activée. Mais dans la vraie vie mon contrôle est plus complexe et la frontière est là pour une raison. Mais cela peut être résolu par les liaisons en cascade:

<DockPanel x:Name="Wrapper" Grid.Row="2" > 
    <Border x:Name="MyBorder" BorderBrush="CadetBlue" BorderThickness="1" Width="{Binding ElementName=Wrapper, Path=ActualWidth}" > 
     <RichTextBox x:Name="RichBox" Width="{Binding ElementName=MyBorder, Path=Width}" /> 
    </Border> 
</DockPanel> 

Il semble que la liaison à ActualWidth ne fonctionne pas comme prévu si vous liez à un grand-parent ou d'un ancêtre plus lointain. C'est apparemment pourquoi la suggestion de Sinatr ne fonctionne pas non plus.

+0

Je ne comprends pas ce que vous problème est que vous devriez être en mesure de le faire avec la [par défaut mise en page] (https://wpftutorial.net/LayoutProperties.html) –

+0

Vérifiez si votre RichTextBox a une certaine valeur MinWidth élevée. Peut-être que si vous abaissez cette valeur, cela ne va pas étirer la fenêtre? – Mishka

+0

Ne devriez-vous pas «ancrer» la bordure à «DockPanel»? Essayez d'ajouter l'attribut 'DockPanel.Dock = Left' à votre frontière et voyez si vous obtenez ce que vous voulez. – praty

Répondre

0

SizeToContent = "Largeur" ​​

Vous voulez que la fenêtre autoSize à DataGrid largeur?

RichTextBox semble spécial, il demandera l'espace disponible maximum à partir de son conteneur parent, occupant toute la largeur combinée de bureau à volonté.Une solution facile est de limiter la largeur de celui-ci:

<Grid> 
    <DataGrid x:Name="dataGrid" /> 
    <DockPanel> 
     <Border> 
      <RichTextBox Width="{Binding ActualWidth, ElementName=dataGrid}" /> 
     </Border> 
    </DockPanel> 
</Grid> 
1

Une solution facile serait de régler le Width du RichTextBox-0 dans le balisage XAML et gérer son événement Loaded et régler la Width à la largeur de la fenêtre une fois il a été chargé:

<RichTextBox Width="0" Loaded="RichTextBox_Loaded" /> 

private void RichTextBox_Loaded(object sender, RoutedEventArgs e) 
{ 
    RichTextBox rtb = sender as RichTextBox; 
    rtb.Width = this.Width; 
}