Wpf 如何根据XAML中的窗口或屏幕大小设置网格列MaxWidth
我在窗口中有一个3列网格,第一列上有一个网格拆分器。我想将第一列的MaxWidth设置为父窗口或页面的三分之一Wpf 如何根据XAML中的窗口或屏幕大小设置网格列MaxWidth,wpf,xaml,width,actualwidth,Wpf,Xaml,Width,Actualwidth,我在窗口中有一个3列网格,第一列上有一个网格拆分器。我想将第一列的MaxWidth设置为父窗口或页面的三分之一宽度(或实际宽度),如果可能的话,我更愿意使用XAML 这是一些在XamlPad(或类似)中使用的XAML示例,它显示了我正在做什么 <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorli
宽度
(或实际宽度
),如果可能的话,我更愿意使用XAML
这是一些在XamlPad(或类似)中使用的XAML示例,它显示了我正在做什么
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" Width="200"/>
<ColumnDefinition x:Name="Column2" MinWidth="50" />
<ColumnDefinition x:Name="Column3" Width="{ Binding ElementName=Column1, Path=Width }"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green" />
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Page>
如您所见,右列的宽度与第一列的宽度绑定,因此当您使用拆分器滑动左列时,右列也会执行相同的操作:)
如果将左列向右滑动,它最终将滑过页面/窗口的一半并滑向窗口的右侧,从而推开第2列和第3列
我想通过将第1列的MaxWidth设置为窗口宽度的三分之一(或类似的值)来防止这种情况。我可以很容易地在代码隐藏中做到这一点,但如何在“仅XAML”中做到这一点呢
编辑:David Schmitt建议使用SharedSizeGroup而不是binding,这是一个很好的建议。我的示例代码如下所示:
我懒得亲自编写,但您应该能够使用数学转换器并绑定到父窗口宽度(通过名称或相对资源祖先搜索)
我认为仅使用XAML的方法有点迂回,但这里有一种方法可以做到这一点
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<!-- This contains our real grid, and a reference grid for binding the layout-->
<Grid x:Name="Container">
<!-- hidden because it's behind the grid below -->
<Grid x:Name="LayoutReference">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- We need the border, because the column doesn't have an ActualWidth -->
<Border x:Name="ReferenceBorder"
Background="Black" />
<Border Background="White" Grid.Column="1" />
<Border Background="Black" Grid.Column="2" />
</Grid>
<!-- I made this transparent, so we can see the reference -->
<Grid Opacity="0.9">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1"
MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
<ColumnDefinition x:Name="Column2"
MinWidth="50" />
<ColumnDefinition x:Name="Column3"
Width="{ Binding ElementName=Column1, Path=Width }"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green"/>
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Grid>
</Page>
请使用SharedSizeGroup,而不是绑定到另一列的宽度!我在XamlPad中尝试了上面的xaml,它的行为有点奇怪,但我明白你的意思!谢谢
//I know I borrowed this from someone, sorry I forgot to add a comment from whom
public class ScaledValueConverter : IValueConverter
{
public Object Convert(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
{
Double scalingFactor = 0;
if (parameter != null)
{
Double.TryParse((String)(parameter), out scalingFactor);
}
if (scalingFactor == 0.0d)
{
return Double.NaN;
}
return (Double)value * scalingFactor;
}
public Object ConvertBack(Object value, Type targetType, Object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("The method or operation is not implemented.");
}
}
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<!-- This contains our real grid, and a reference grid for binding the layout-->
<Grid x:Name="Container">
<!-- hidden because it's behind the grid below -->
<Grid x:Name="LayoutReference">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- We need the border, because the column doesn't have an ActualWidth -->
<Border x:Name="ReferenceBorder"
Background="Black" />
<Border Background="White" Grid.Column="1" />
<Border Background="Black" Grid.Column="2" />
</Grid>
<!-- I made this transparent, so we can see the reference -->
<Grid Opacity="0.9">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1"
MaxWidth="{Binding ElementName=ReferenceBorder,Path=ActualWidth}"/>
<ColumnDefinition x:Name="Column2"
MinWidth="50" />
<ColumnDefinition x:Name="Column3"
Width="{ Binding ElementName=Column1, Path=Width }"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Background="Green"/>
<GridSplitter Grid.Column="0" Width="5" />
<Label Grid.Column="1" Background="Yellow" />
<Label Grid.Column="2" Background="Red" />
</Grid>
</Grid>
</Page>