I can't figure out how to manage properly the width of a grid column with a user control in one of its cell. I have this xaml for a window:
我不知道如何正确地管理网格列的宽度,并在其中一个单元格中使用用户控件。我有这个xaml作为窗户:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Content="Button" Width="100" HorizontalAlignment="Left"/>
<TextBox Grid.Row="1" />
<local:UserControl1 Grid.Row="2"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
and the user control is a drawing set to stretch as needed:
用户控件是根据需要拉伸的绘图集:
<UserControl x:Class="WpfApplication1.UserControl1"
Height="auto" Width="auto">
<Grid Background="Aqua">
<Path Fill="Coral" Stroke="Black" StrokeThickness="1"
Stretch="Uniform"
HorizontalAlignment="Left" VerticalAlignment="Top">
<Path.Data>
<RectangleGeometry Rect="40,20, 140,30" RadiusX="10" RadiusY="10" />
</Path.Data>
</Path>
</Grid>
</UserControl>
To help I have set the user control background in blue.
为了帮助我将用户控制背景设置为蓝色。
I would like to have the width of the column ignoring the "natural" size of the user control. I mean I would like the user control to not determine the width during the layout of the column, but to adjust its width to whatever is the width of the column.
我希望列的宽度忽略用户控件的“自然”大小。我的意思是,我希望用户控件不要在列布局期间确定宽度,而是将其宽度调整为列的宽度。
In the example, initially the Grid would set the column width to the value of the button, and the user control would use the column width to resize itself. Then if a long text is entered in the Textbox, as soon as the Textbox starts to be wider than the button, and the column starts to be resized as well, in turn the user control would adjust to maintain the same size than the column.
在本例中,最初网格将列宽度设置为按钮的值,用户控件将使用列宽度来调整自己的大小。然后,如果在文本框中输入一个长文本,当文本框开始比按钮宽,并且列也开始调整大小时,用户控件就会相应地调整以保持列的大小。
I've tried combinations of stretch values, and also have used MeasureOverride() in the user control. The latter doesn't work because the AvalaibleSize received is Infinity, not the column width.
我尝试了拉伸值的组合,并在用户控件中使用了MeasureOverride()。后者不起作用,因为接受的AvalaibleSize是无穷大,而不是列宽。
2 个解决方案
#1
7
I was able to achieve what (I believe) you're looking for by giving the TextBox a name, and binding the width of the UserControl to the ActualWidth of the TextBox. Here's the code for the Window's Grid:
我可以通过给文本框起一个名字,并将用户控件的宽度绑定到文本框的实际宽度来实现(我相信)。这是窗口网格的代码:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Content="Button" Width="100" HorizontalAlignment="Left"/>
<TextBox Grid.Row="1" x:Name="entryTextBox" />
<local:UserControl1 Grid.Row="2"
Width="{Binding ElementName=entryTextBox, Path=ActualWidth}"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
Hope that helps!
希望会有帮助!
#2
2
Old question, so it will probably not help OP anymore, but it may help others:
老问题,所以它可能不会再帮助OP,但它可能会帮助其他人:
Put UserControl1 inside a Canvas. Then bind the Width to the ActualWidth of the parent Grid.
将UserControl1放在画布中。然后将宽度绑定到父网格的实际宽度。
Example:
例子:
<Grid Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Something Grid.Row="0"/>
<Canvas Grid.Row="1">
<MyControl Width="{Binding ActualWidth, ElementName=mainGrid, Mode=OneWay}"/>
</Canvas>
</Grid>
The canvas will take the available width, but will never ask Grid for more. The controls inside the canvas get no size from Canvas, so you must give it a size manually. In this case, we want to give it the size of the parent Grid.
画布将使用可用的宽度,但不会向Grid索取更多。画布内部的控件不会从画布中获得大小,所以您必须手动给它一个大小。在这种情况下,我们想给它父网格的大小。
#1
7
I was able to achieve what (I believe) you're looking for by giving the TextBox a name, and binding the width of the UserControl to the ActualWidth of the TextBox. Here's the code for the Window's Grid:
我可以通过给文本框起一个名字,并将用户控件的宽度绑定到文本框的实际宽度来实现(我相信)。这是窗口网格的代码:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Content="Button" Width="100" HorizontalAlignment="Left"/>
<TextBox Grid.Row="1" x:Name="entryTextBox" />
<local:UserControl1 Grid.Row="2"
Width="{Binding ElementName=entryTextBox, Path=ActualWidth}"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
Hope that helps!
希望会有帮助!
#2
2
Old question, so it will probably not help OP anymore, but it may help others:
老问题,所以它可能不会再帮助OP,但它可能会帮助其他人:
Put UserControl1 inside a Canvas. Then bind the Width to the ActualWidth of the parent Grid.
将UserControl1放在画布中。然后将宽度绑定到父网格的实际宽度。
Example:
例子:
<Grid Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Something Grid.Row="0"/>
<Canvas Grid.Row="1">
<MyControl Width="{Binding ActualWidth, ElementName=mainGrid, Mode=OneWay}"/>
</Canvas>
</Grid>
The canvas will take the available width, but will never ask Grid for more. The controls inside the canvas get no size from Canvas, so you must give it a size manually. In this case, we want to give it the size of the parent Grid.
画布将使用可用的宽度,但不会向Grid索取更多。画布内部的控件不会从画布中获得大小,所以您必须手动给它一个大小。在这种情况下,我们想给它父网格的大小。