You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms网格按钮异常:8个正方形1个矩形的解决咨询

解决Xamarin Forms Grid中3x3正方形按钮布局异常问题

嘿,我看了你的代码,立刻发现了导致出现8个正方形1个矩形按钮的问题所在!

问题根源

  • Grid行高设置错误:你给RowDefinition用了Height="Auto",这会让行高根据按钮内容自适应,但按钮的HeightRequest又绑定了自身Width,这就造成了布局计算循环——按钮高度依赖宽度,而行高又依赖按钮高度,最后某个按钮的尺寸计算会出现偏差。
  • 布局选项冲突:按钮的VerticalOptions="CenterAndExpand"和HorizontalOptions="Fill"搭配,在Auto行高的情况下,无法稳定保持正方形比例。

修复方案

我们需要让Grid的行和列尺寸严格对等,同时避免布局循环:

  1. 将Grid的RowDefinition.Height从Auto改为*,让三行平分Grid可用高度,和列的Width="*"保持一致,确保每行每列的单元格尺寸相同。
  2. 给Grid本身设置正方形约束(绑定HeightRequest到自身Width),确保整个Grid是正方形,里面的单元格自然也是正方形。
  3. 简化按钮布局选项,让按钮填充满整个单元格,再通过绑定HeightRequest到自身宽度来保障正方形比例。

修改后的完整XAML代码

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:d="http://xamarin.com/schemas/2014/forms/design" 
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             mc:Ignorable="d" 
             x:Class="Chess_test13.MainPage">
    <StackLayout>
        <!-- 让Grid保持正方形,绑定HeightRequest到自身Width -->
        <Grid Padding="50,50" 
              RowSpacing="0" 
              ColumnSpacing="0"
              HeightRequest="{Binding Source={x:Reference thisGrid}, Path=Width}">
            <Grid x:Name="thisGrid">
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <!-- 按钮简化布局,填充满单元格,高度绑定到自身宽度 -->
                <Button x:Name="00" ClassId="00" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="0" Grid.Column="0" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 00}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="01" ClassId="01" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="0" Grid.Column="1" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 01}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="02" ClassId="02" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="0" Grid.Column="2" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 02}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="10" ClassId="10" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="1" Grid.Column="0" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 10}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="11" ClassId="11" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="1" Grid.Column="1" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 11}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="12" ClassId="12" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="1" Grid.Column="2" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 12}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="20" ClassId="20" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="2" Grid.Column="0" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 20}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="21" ClassId="21" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="2" Grid.Column="1" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 21}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
                <Button x:Name="22" ClassId="22" PropertyChanged="PropertyChanged" 
                        Text="" Grid.Row="2" Grid.Column="2" BackgroundColor="Transparent" 
                        Clicked="buttonClick" 
                        HeightRequest="{Binding Source={x:Reference 22}, Path=Width}"
                        HorizontalOptions="Fill" VerticalOptions="Fill" />
            </Grid>
        </Grid>
    </StackLayout>
</ContentPage>

额外说明

  • 外层Grid绑定HeightRequest到自身Width,确保整个Grid是正方形,里面的3x3单元格自然都保持正方形比例。
  • 按钮的HorizontalOptions和VerticalOptions设为Fill,让按钮完全填充单元格,再加上HeightRequest绑定自身宽度,双重保障正方形效果。
  • 把RowDefinition.Height改成*后,三行平分Grid高度,和列的*宽度匹配,彻底避免了布局循环问题。

内容的提问来源于stack exchange,提问作者Brad Stephen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:04:40