Xamarin Forms网格按钮异常:8个正方形1个矩形的解决咨询
解决Xamarin Forms Grid中3x3正方形按钮布局异常问题
嘿,我看了你的代码,立刻发现了导致出现8个正方形1个矩形按钮的问题所在!
问题根源
- Grid行高设置错误:你给
RowDefinition用了Height="Auto",这会让行高根据按钮内容自适应,但按钮的HeightRequest又绑定了自身Width,这就造成了布局计算循环——按钮高度依赖宽度,而行高又依赖按钮高度,最后某个按钮的尺寸计算会出现偏差。 - 布局选项冲突:按钮的
VerticalOptions="CenterAndExpand"和HorizontalOptions="Fill"搭配,在Auto行高的情况下,无法稳定保持正方形比例。
修复方案
我们需要让Grid的行和列尺寸严格对等,同时避免布局循环:
- 将Grid的
RowDefinition.Height从Auto改为*,让三行平分Grid可用高度,和列的Width="*"保持一致,确保每行每列的单元格尺寸相同。 - 给Grid本身设置正方形约束(绑定
HeightRequest到自身Width),确保整个Grid是正方形,里面的单元格自然也是正方形。 - 简化按钮布局选项,让按钮填充满整个单元格,再通过绑定
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
相关产品推荐
相关产品推荐

