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

发布于 2024-11-02 04:09:59 字数 1845 浏览 0 评论 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.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
            });
    }
}

现在的工作原理: 网格占据整个屏幕高度减去按钮的高度。当添加太多新项目时,您会开始滚动扫描。按钮的位置永远不会改变,它始终位于屏幕底部。

我想要的:网格应该占用尽可能少的空间,因此当它为空时,只有标题应该可见,并且按钮位于其正下方。当添加太多项目并且按钮已经位于屏幕底部时,它不应该再增长,而是开始滚动。

如果我交换两个 RowDefinition,那么网格一开始很小,但会无限增长,将按钮推离屏幕并且永远不会开始滚动。我怎样才能很好地做到这一点?

See the following 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>

Corresponding code:

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
            });
    }
}

How it works now: The grid takes up the entire screen height minus the height of the button. When too many new items are added, you scan start scrolling. The position of the button never changes, it's always at the bottom of the screen.

What I would like: The grid should take up as little space as possible, so when it's empty, only the header should be visible, and the button immediately below it. When too many items are added, and the button is already at the bottom of the screen, it shouldn't grow any more, but start scrolling instead.

If I swap the two RowDefinition's, then the grid is small at first, but grows indefinitely, pushes the button off the screen and never starts scrolling. How can I do this nicely?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

同尘 2024-11-09 04:09:59

为了实现这一目标,请在 LayoutRoot 中嵌套另一个 Grid,然后使用该嵌套网格作为主网格。然后将两行设置为自动

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

在我的实现中,我将此代码包装在一个 UpdateRowPinning 方法中,该方法实际上使用调度程序来调用此代码。然后,我在主网格和内部网格的调整大小事件以及从网格中添加和删除项目以及网格组的展开/折叠操作时调用 UpdateRowPinning。这可以确保第二行通过位于第一行的底部直到屏幕填满然后浮动在其上来正常运行。

我在这里的回答也涵盖了这个问题。我搜索了仅 XAML 的解决方案,但它似乎不可能(除非您编写一些 XAML 扩展,然后您可能能够使用 XAML 来实现它,但这是一种作弊)。

In order to achieve this, nest another Grid in LayoutRoot and then use that nested grid as your main one. Then set both rows to 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>

Finally, you need to track the size of the grid and change the sizing rules accordingly. This "pinning" code looks something like.

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

In my implementation, I wrap this code in an UpdateRowPinning method that actually uses the dispatcher to call this code. I then call UpdateRowPinning on resize events for the main grid and the inner grid as well as on adding and removing items from the grid and expand/collapse operations of grid groups. This ensures that the second row behaves properly by sitting at the base of the first row until the screen is full and then floating over it after that.

My answer here also covers this issue. I searched for a XAML only solution but it just doesn't seem possible (unless you write some XAML extensions, then you might be able to pull it off with XAML but that's kind of cheating).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文