简体   繁体   English

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

[英]WPF How to make RichTextBox width follow that of the parent control?

Here I have the following simple window: 这里有以下简单窗口:

在此输入图像描述

The upper part is a DataGrid, below is a TextBox. 上半部分是DataGrid,下面是TextBox。 The window is set to size to content's width. 窗口设置为内容宽度的大小。 This is the desired layout. 这是所需的布局。

Now I need to display some richtext so I replace the TextBox with RichTextBox. 现在我需要显示一些richtext,所以我用RichTextBox替换TextBox。 The problem is that now the window stretches to the width of the screen, like so (I've shrunk it, of course, but you get the idea): 问题是现在窗口延伸到屏幕的宽度,就像这样(当然,我缩小了它,但你明白了):

在此输入图像描述

I've tried binding the RichTextBox's width to the actual width of the parent: 我已经尝试将RichTextBox的宽度绑定到父级的实际宽度:

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

but it still expands to the entire window. 但它仍然扩展到整个窗口。 BTW the same happens if I use TextBox in the above code. 顺便说一句,如果我在上面的代码中使用TextBox也会发生同样的情况。

How can I make the RichTextBox's width fit to the parent, while still maintaining dynamic window layout? 如何使RichTextBox的宽度适合父级,同时仍保持动态窗口布局? I mean the DataGrid is the key element to which both the windows's width and the RichTextBox's width must be subject to. 我的意思是DataGrid是窗口宽度和RichTextBox宽度都必须遵循的关键元素。

Below is the full code. 以下是完整的代码。

XAML 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# 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. mm8's solution almost works but it seems that Loaded event happens to early to calculate the ActualWidth properly - the RichTextBox doesn't fill the width and leaves gaps. 1. mm8的解决方案几乎可以工作,但似乎Loaded事件发生得很早才能正确计算ActualWidth - RichTextBox没有填充宽度并留下空隙。 But taking the idea further I used the window's "Content_Rendered" event to fix the window's width and then set RichTextBox's width to auto. 但是进一步理解我使用窗口的“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 was spot on. 2. Spongebrot是即期。 Indeed, when the extra border is removed binding to parent's ActualWidth works. 实际上,当删除额外边框时绑定到父级的ActualWidth工作。 But in real life my control is more complex and the border is there for a reason. 但在现实生活中,我的控制更加复杂,边界是有原因的。 But this can be solved by cascading bindings: 但这可以通过级联绑定来解决:

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

It seems that binding to ActualWidth doesn't work as expected if you bind to a grandparent or more distant ancestor. 如果绑定到祖父母或更远的祖先,似乎绑定到ActualWidth不会按预期工作。 This is seemingly why Sinatr's suggestion doesn't work either. 这似乎是为什么Sinatr的建议也不起作用的原因。

An easy workaround would be to set the Width of the RichTextBox to 0 in the XAML markup and then handle its Loaded event and set the Width to the window's width once it has been loaded: 一个简单的解决方法是在XAML标记中将RichTextBoxWidth设置为0 ,然后处理其Loaded事件并在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;
}

SizeToContent="Width" SizeToContent = “宽度”

So you want the window to autosize to DataGrid width? 所以你想让窗口自动调整到DataGrid宽度?

RichTextBox seems special, it will request maximum available space from its parent container, occupying the whole combined desktops width at will. RichTextBox看起来很特别,它将从其父容器请求最大可用空间,随意占用整个组合桌面宽度。 An easy fix is to limit width of it: 一个简单的解决方法是限制它的宽度:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM