.net ImageButton.Click事件在其顶部渲染1个标签而不是2个标签的情况下工作

xzv2uavs  于 2023-05-30  发布在  .NET
关注(0)|答案(1)|浏览(102)

在Windows中运行时,这似乎是一个问题(尚未测试任何其他平台):
我有一个单行和单列网格与它里面的ImageButton。
然后我在Grid中添加了一个Label,这样它就可以呈现在ImageButton的顶部。到目前为止一切顺利,Click事件在ImageButton上工作。
在此之后,我向同一个Grid添加了一个Label,因此它会呈现在另一个Label和ImageButton的顶部,并且Click事件停止工作。怎么了?
这个用户界面的目的是为一个拼字游戏,我做的。这个特殊的元素是tile,它是一个具有适当背景颜色的ImageButton,第一个Label表示字母,第二个Label表示该字母的值。示例:

代码:

// BoardCell.cs Class for the Scrabble Letter Tile
public class BoardCell : StackLayout
{
    public ImageButton TileImageButton { get; private set; }
    public Label TileLetterLabel { get; private set; }
    public Label TileValueLabel { get; private set; }

    public BoardCell(Enums.BoardCellTypes boardCellType)
    {
        // Setup the TileImageButton
        TileImageButton = new ImageButton();
        TileImageButton.WidthRequest = 80;
        TileImageButton.HeightRequest = 80;
        TileImageButton.BorderColor = Colors.DarkGray;
        TileImageButton.BorderWidth = 2;

        // Setup the Tile Grid
        var tileGrid = new Grid();
        tileGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Star });
        tileGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });

        // Add the Tile Image Button
        tileGrid.Children.Add(TileImageButton);
        Grid.SetRow(TileImageButton, 0);
        Grid.SetColumn(TileImageButton, 0);

        // Setup and add the Tile Letter Label
        TileLetterLabel = new Label();
        TileLetterLabel.TextColor = Colors.Black;
        TileLetterLabel.FontSize = 48;
        TileLetterLabel.FontAttributes = FontAttributes.Bold;
        TileLetterLabel.HorizontalTextAlignment = TextAlignment.Center;
        TileLetterLabel.VerticalTextAlignment = TextAlignment.Center;
        TileLetterLabel.IsVisible = false; // Important this is initially false, otherwise it blocks clicks on the TileImageButton behind it

        tileGrid.Children.Add(TileLetterLabel);
        Grid.SetRow(TileLetterLabel, 0);
        Grid.SetColumn(TileLetterLabel, 0);

        // Setup and add the Tile Value Label
        TileValueLabel = new Label();
        TileValueLabel.TextColor = Colors.Black;
        TileValueLabel.FontSize = 12;
        TileValueLabel.FontAttributes = FontAttributes.Bold;
        TileValueLabel.HorizontalTextAlignment = TextAlignment.Center;
        TileValueLabel.VerticalTextAlignment = TextAlignment.End;

        tileGrid.Children.Add(TileValueLabel);
        Grid.SetRow(TileValueLabel, 0);
        Grid.SetColumn(TileValueLabel, 0);

        // Add the tileGrid to the StackLayout of this control
        this.Children.Add(tileGrid);

        if (boardCellType == Enums.BoardCellTypes.TileLetter)
        {
            SetTileValueLabel();
            TileLetterLabel.IsVisible = true;
        }
        else
        {
            TileLetterLabel.IsVisible = false;
        }
    }

    public void SetTileValueLabel()
    {
        this.TileValueLabel.Text = this.TileValue.ToString();
    }
}
// MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    BoardCell SelectedTile { get; set; }

    public MainPage()
    {
        BoardTileTapGestureRecognizer = new TapGestureRecognizer();
        BoardTileTapGestureRecognizer.Tapped += BoardTileTapGestureRecognizer_Tapped;

        InitializeBoard();

        MyTileTapGestureRecognizer = new TapGestureRecognizer();
        MyTileTapGestureRecognizer.Tapped += MyTileTapGestureRecognizer_Tapped;
    }

    private void BoardTileTapGestureRecognizer_Tapped(object sender, EventArgs e)
    {
      // Does a bunch of stuff, but this event doesn't fire with this bug
    }

    private void MyTileTapGestureRecognizer_Tapped(object sender, EventArgs e)
    {
        // This one does fire
        SelectedTile = GetBoardCellParent(sender); // Sets the SelectedTile to clicked on BoardCell object
    }
}
private void InitializeBoard()
{
    for (int row = 0; row <= 14; row++)
    {
        // Setup new row and column for gameboard (only need to do this 15 times for each for a 15x15 grid)
        var tileRowDefinition = new RowDefinition() { Height = 80 };
        var tileColumnDefinition = new ColumnDefinition() { Width = 80 };

        grid_GameBoard.RowDefinitions.Add(tileRowDefinition);
        grid_GameBoard.ColumnDefinitions.Add(tileColumnDefinition);

        for (int column = 0; column <= 14; column++)
        {
            // Create a new board cell and set it's clicked event
            BoardCell boardCell = GetNewBoardCell(row, column);
            boardCell.TileImageButton.Clicked += OnBoardCellClicked;
            boardCell.TileLetterLabel.GestureRecognizers.Add(BoardTileTapGestureRecognizer);

            // Add the new board cell to the grid                
            grid_GameBoard.Children.Add(boardCell);
            Grid.SetRow(boardCell, row);
            Grid.SetColumn(boardCell, column);
        }
    }
private void OnBoardCellClicked(object sender, EventArgs e)
{
  // Does a few things but never gets hit with this bug
}
// MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ScrabbleMaui2.MainPage">

    <ScrollView>
        <!--<Grid RowSpacing="25" RowDefinitions="Auto,Auto,Auto,Auto,*"
              Padding="{OnPlatform iOS='30,60,30,30', Default='30'}">-->

        <Grid x:Name="grid_Game" RowDefinitions="50,*,100" ColumnDefinitions="*" MaximumHeightRequest="1500">
            <Grid x:Name="grid_TitleBar" Grid.Row="0" ColumnDefinitions="*,*,*">
                <Grid x:Name="grid_Score" ColumnDefinitions="*,*">
                    <Label Grid.Column="0" Text="My Score: " />
                    <Label x:Name="lbl_MyScore" Grid.Column="1" Text="0" />
                </Grid>

                <Button x:Name="btn_SubmitPlay" Grid.Column="2" Text="Play Word" WidthRequest="100" Clicked="btn_SubmitPlay_Clicked" />
            </Grid>

            <Grid x:Name="grid_GameBoard" Grid.Row="1" Margin="10" HorizontalOptions="Center" BackgroundColor="Green" />

            <Grid x:Name="grid_MyTiles" Grid.Row="2" RowDefinitions="Auto" ColumnDefinitions="*,*,*,*,*,*,*" MaximumWidthRequest="620"
                  BackgroundColor="Blue" />
        </Grid>
    </ScrollView>

</ContentPage>

根据ToolmakerSteve的建议,我重新排列了用于构建Tile对象的控件。我现在把一个透明的按钮放在最后,所以它被渲染为最上面的元素。下面是BoardCell.cs构造函数中的新代码:

public BoardCell(Enums.BoardCellTypes boardCellType, bool isCenterCell)
{
    this.IsLocked = false;
    this.BoardCellType = boardCellType;
    this.IsCenterCell = isCenterCell;

    var tileGrid = new Grid();
    tileGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Star });
    tileGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Star });

    TileBackground = new Image();
    TileLetterLabel = GetLetterLabel();
    TileValueLabel = GetValueLabel();

    SetTileBackground();
    SetTileValueLabel();

    TileButton = new Button();
    TileButton.WidthRequest = 80;
    TileButton.HeightRequest = 80;
    TileButton.IsVisible = false;

    tileGrid.Children.Add(TileBackground);
    tileGrid.Children.Add(TileLetterLabel);
    tileGrid.Children.Add(TileValueLabel);
    tileGrid.Children.Add(TileButton);

    Grid.SetRow(TileBackground, 0);
    Grid.SetRow(TileLetterLabel, 0);
    Grid.SetRow(TileValueLabel, 0);
    Grid.SetRow(TileButton, 0);

    Grid.SetColumn(TileBackground, 0);
    Grid.SetColumn(TileLetterLabel, 0);
    Grid.SetColumn(TileValueLabel, 0);
    Grid.SetColumn(TileButton, 0);

    this.Children.Add(tileGrid);
}

我现在使用一个单独的Image元素作为背景,并使用一个常规的Button元素进行单击。不幸的是,我仍然表现出同样的行为,奇怪的是。只要TileValueLabel作为子元素添加到Grid,按钮的Click事件就不会触发。如果我注解掉将其添加到Grid-tileGrid.Children.Add(TileValueLabel);的行,则Click事件将触发。

kulphzqa

kulphzqa1#

听起来像是有一个通过多个元素传递输入的错误。
尝试将两个标签 Package 在第二个网格中,InputTransparent位于内部网格上:

<Grid ..>
  <ImageButton ../>
  <Grid InputTransparent="True">
    <Label ../>
    <Label ../>
  </Grid>
</Grid>

相关问题