silverlight xaml布局问题:网格应该能够增长,但不能脱离屏幕

silverlight xaml布局问题:网格应该能够增长,但不能脱离屏幕,xaml,silverlight-4.0,Xaml,Silverlight 4.0,请参见以下XAML: <UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsof

请参见以下XAML:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication1.MainPage"
    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"
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" MinHeight="150">
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <sdk:DataGrid x:Name="grid" VerticalScrollBarVisibility="Visible" />
        <Button x:Name="button" Grid.Row="1" Content="hello" VerticalAlignment="Top" HorizontalAlignment="Center" Click="button_Click" />
    </Grid>
</UserControl>

对应代码:

public partial class MainPage : UserControl
{
    public class dataclass
    {
        public string data { get; set; }
    }

    ObservableCollection<dataclass> list;

    public MainPage()
    {
        InitializeComponent();
        grid.ItemsSource = list = new ObservableCollection<dataclass>();
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        for (var i = 0; i < 5; i++)
            list.Add(new dataclass
            {
                data = "hello" + i
            });
    }
}
public部分类主页面:UserControl
{
公共类数据类
{
公共字符串数据{get;set;}
}
可观察收集清单;
公共主页()
{
初始化组件();
grid.ItemsSource=list=new ObservableCollection();
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
对于(变量i=0;i<5;i++)
添加(新的数据类)
{
data=“hello”+i
});
}
}
它现在的工作原理:网格占据整个屏幕高度减去按钮高度。当添加太多新项目时,您可以开始滚动。按钮的位置永远不会改变,它始终位于屏幕底部

我想要的是:网格应该占据尽可能少的空间,所以当它是空的,只有标题应该是可见的,按钮就在它下面。当添加了太多的项目,并且按钮已经位于屏幕底部时,它不应该再增长,而是开始滚动


如果我交换两行定义,那么网格一开始很小,但会无限增长,按下屏幕上的按钮,永远不会开始滚动。如何才能很好地做到这一点?

为了实现这一点,在
LayoutRoot
中嵌套另一个
网格
,然后将该嵌套网格用作主网格。然后将两行设置为
Auto

 <Grid x:Name="LayoutRoot" Background="White">
     <Grid x:Name="innerGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid x:Name="itemInTheFirstRow" Grid.Row="0" />
        <Button x:Name="itemInTheSecondRow" Grid.Row="1" />
     </Grid>
 </Grid>

最后,您需要跟踪网格的大小,并相应地更改大小调整规则。这个“固定”代码看起来像

RowDefinition row = this.innerGrid.RowDefinitions[0];
if (row.Height.GridUnitType == GridUnitType.Auto)
{
    if (this.innerGrid.ActualHeight > this.ActualHeight)
    {
        row.Height = new GridLength(1, GridUnitType.Star);
    }
}
else
{
    if (this.itemInTheFirstRow.DesiredSize.Height < row.ActualHeight)
    {
        row.Height = GridLength.Auto;
    }
}
RowDefinition行=this.innerGrid.RowDefinitions[0];
if(row.Height.GridUnitType==GridUnitType.Auto)
{
如果(this.innergid.ActualHeight>this.ActualHeight)
{
row.Height=新的GridLength(1,GridUnitType.Star);
}
}
其他的
{
if(this.itemInTheFirstRow.DesiredSize.Height
在我的实现中,我将此代码包装在一个
UpdateRowPinning
方法中,该方法实际使用dispatcher调用此代码。然后,我调用
UpdateRowPinning
来调整主网格和内部网格的事件大小,以及从网格中添加和删除项目,以及展开/折叠网格组的操作。这可以确保第二行的行为正常,即坐在第一行的底部,直到屏幕满了,然后在屏幕上浮动


也包括这个问题。我搜索了一个只有XAML的解决方案,但似乎不可能(除非您编写一些XAML扩展,否则您可能可以使用XAML实现它,但这是一种欺骗)。

是的,这就是我在写“很好地做到这一点”时所担心的。无论如何,谢谢你,如果没有XAML的唯一方法,那么这就是我要做的。@fejesjoco:我不会害怕这个解决方案。对于每种情况都没有一个XAML唯一的解决方案,您需要的是一个没有自定义支持的复杂行为。您可以创建自己的面板控件来包装此行为以供将来使用。这样,您只需要实现一次,然后在仅XAML的情况下永远使用它。