WPF如何使RichTextBox的宽度跟随父控件的宽度?

WPF如何使RichTextBox的宽度跟随父控件的宽度?

问题描述:

这里我有以下简单的窗口:WPF如何使RichTextBox的宽度跟随父控件的宽度?

enter image description here

上部是一个数据网格,下面是一个文本框。该窗口的大小设置为内容的宽度。这是所需的布局。

现在我需要显示一些富文本,所以我用RichTextBox替换TextBox。问题是,现在的窗口延伸到屏幕的宽度,像这样(我已经缩小它,当然,但你的想法):

enter image description here

我试着结合RichTextBox中的宽度为父级的实际宽度:

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

但它仍然扩展到整个窗口。顺便说一句,如果我在上面的代码中使用TextBox也会发生同样的情况。

如何让RichTextBox的宽度适合父级,同时仍然保持动态窗口布局?我的意思是DataGrid是窗口宽度和RichTextBox宽度都必须遵守的关键因素。

以下是完整的代码。

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

MM8的解决方案几乎工程,但它似乎Loaded事件发生在早期正确计算ActualWidth的 - RichTextBox不会填充wid并留下空白。但进一步考虑这个想法后,我使用窗口的“Content_Rendered”事件来修复窗口的宽度,然后将RichTextBox的宽度设置为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是点上。事实上,当额外的边框被删除绑定到父母的ActualWidth作品。但在现实生活中,我的控制更复杂,边界在那里是有原因的。但是,这可以通过级联的绑定来解决:

<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> 

似乎绑定到ActualWidth的,如果你绑定到祖父母或更遥远的祖先没有按预期工作。这似乎是为什么Sinatr的建议不起作用。

+0

我不明白你的问题,你应该是什么能够与[默认做到这一点布局](https://wpftutorial.net/LayoutProperties.html) –

+0

检查您的RichTextBox是否具有某个较高的MinWidth。 也许如果你降低这个值,它不会拉伸窗户? – Mishka

+0

如果您不将'Dock'边框“DockPanel”?尝试添加属性'DockPanel.Dock = Left'到你的边框,看看你是否得到你想要的。 – praty

SizeToContent = “宽度”

所以,你要的窗口自动调整到DataGrid宽度?

RichTextBox看起来很特别,它会从其父容器请求最大可用空间,随意占用整个组合桌面宽度。一个简单的办法是限制它的宽度:

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

一个简单的解决方法是将RichTextBoxWidth设置为0在XAML标记,然后处理其Loaded事件,并设置Width到窗口的宽度一次它已经被加载:

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

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