C# XAML在控件之间划分高度
我有一个按网格分割的窗口(左-中-右),其中的中心控件我希望有多个控件,这些控件需要填充尽可能高的高度,同时在其他控件之间均匀分割 我实现这一点的一种方法是通过这样的网格:C# XAML在控件之间划分高度,c#,wpf,xaml,C#,Wpf,Xaml,我有一个按网格分割的窗口(左-中-右),其中的中心控件我希望有多个控件,这些控件需要填充尽可能高的高度,同时在其他控件之间均匀分割 我实现这一点的一种方法是通过这样的网格: <!-- Center --> <Grid Grid.Row="0" Grid.Column="2" Height="Auto"> <Grid.RowDefinitions> <RowDefinition Height="*" />
<!-- Center -->
<Grid Grid.Row="0" Grid.Column="2" Height="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<WebBrowser Grid.Row="0" Name="browsc" />
<WebBrowser Grid.Row="1" Name="browsa" />
<WebBrowser Grid.Row="2" Name="browsb" />
</Grid>
这是有效的,但是我需要动态地添加和删除行,因为中间可能需要删除一行(这就需要重新排序每个控件所依赖的行,我无法想象一个简单的解决方案)。 如果没有比这更好的分割控件的方法,我将如何通过代码(C#)添加和删除行
如果有更好的方法,我该怎么做呢?我所要担心的就是添加和删除控件本身,而不是弄乱行属性谢谢 这是一个示例,介绍如何以编程方式将新的
行定义添加到网格,并将控件设置为特定的网格行:
//following line equal to XAML : <RowDefinition Height="*" />
var newrow = new RowDefinition {Height = new GridLength(1, GridUnitType.Star)};
//add new rowdefinition to grid
myGridName.RowDefinitions.Add(newrow);
//set webbrowser control to newly added row, or any row number you wish
Grid.SetRow(browsx, myGridName.RowDefinitions.Count-1);
//以下行等于XAML:
var newrow=newrowdefinition{Height=newgridlength(1,GridUnitType.Star)};
//将新的行定义添加到网格
myGridName.RowDefinitions.Add(newrow);
//将webbrowser控件设置为新添加的行或任何您想要的行号
SetRow(browsx,myGridName.RowDefinitions.Count-1);
您可以从myGridName.RowDefinitions
属性访问任何RowDefinition
,以便稍后删除它。但更好的办法是将RowDefinition的高度设置为零,而不是将其删除。这样,您就不必重新排列其他控件,例如,将第3行中的控件移动到第2行,因为前一行第2行已被删除。仍然使用网格的另一种可能性是将高度绑定到转换器,该转换器使用其包含的控件的可见性来决定布局
下面是一个例子:
在XAML文件中:
<Grid Grid.Row="0" Grid.Column="2" Height="Auto" xmlns:local="clr-namespace:WpfApplication2">
<Grid.Resources>
<local:RowHeightConverter x:Key="RowHeightConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=browsc, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
<RowDefinition Height="{Binding ElementName=browsa, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
<RowDefinition Height="{Binding ElementName=browsb, Path=IsVisible, Converter={StaticResource RowHeightConverter}}" />
</Grid.RowDefinitions>
<WebBrowser Grid.Row="0" Name="browsc"></WebBrowser>
<WebBrowser Grid.Row="1" Name="browsa" Visibility="Collapsed"></WebBrowser>
<WebBrowser Grid.Row="2" Name="browsb"></WebBrowser>
</Grid>
一旦构建了一次代码,就可以在XAML设计器中更改浏览器的“可见性”,并查看布局中反映的更改。这似乎是一个很好的例子:
UniformGrid
确保所有项目的宽度和高度都相同。在本例中,您只希望约束高度,但由于只有一列,所有项目的宽度都必须相同,因此这是可以的
我们不需要设置行,只需在UniformGrid
上设置Columns=“1”
,它就会自动在新行上排列每个项目。如果您添加或删除项目,或在可见
和折叠
之间切换项目的可见性
,所有大小都将调整以适应空间。您需要多大的动态性?如果您只需要选择性地隐藏中间行,您可以将其内容的可见性设置为折叠
。如果你需要支持任意数量的行,那么如果我设置中间行的可见性崩溃,它将不工作,它只是在中间形成了一个不可见的间隔,因为那里仍然应该有一行。但我最终希望支持任意数量的行。范围从2到5或6不等,这取决于用户选择的数量和屏幕大小(最终他们甚至无法查看每个屏幕中显示的数据)。为什么不使用StackPanel
,当您添加或删除UI元素时,它会自动调整?控件没有垂直拉伸以均匀填充。至少不是以我尝试的方式,再一次,我的XAML体验是非常具有介绍性的。好吧,我认为以这种方式添加一个网格行不会太糟糕。删除一行怎么样?上面已经解释过,myGridName.RowDefinitions[rownumber]
将为您提供一个RowDefinition对象。您可以删除该对象以删除行定义,或者根据我的喜好将其高度设置为0。哦,我的错。这就是我只扫描代码片段得到的结果。我非常喜欢将高度设置为0的想法。这似乎奏效了。在我选择被接受的答案之前,我将等待是否有人提出另一个解决方案:)完美!我知道必须有一个简单的方法来做到这一点。谢谢你让我注意到这个控件!
public class RowHeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var isVisible = value as bool?;
if (isVisible.HasValue && isVisible.Value)
return new GridLength(1, GridUnitType.Star);
else
return new GridLength(0);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
<UniformGrid Grid.Row="0" Grid.Column="2" Columns="1">
<WebBrowser Name="browsc" />
<WebBrowser Name="browsa" />
<WebBrowser Name="browsb" />
</UniformGrid>