Xamarin.Forms 绑定不适用于嵌套的自定义控件

Xamarin.Forms binding does not work with nested custom controls

我正在尝试创建一个简单的(数独)网格,它基本上由 9 个自定义(网格)控件组成,其中每个控件都包含 9 个其他自定义(网格)控件。但是,绑定似乎在 GridCell 控件中不起作用。外部 GridBigCell 控件似乎工作正常,我可以看到它在调试时绑定到 OuterCell 属性。

代码非常简单,这甚至可能不是创建这样一个网格的好方法,但此时我只是好奇这里的问题是什么:)

MainPage.xaml:

    <Grid>
        <controls:GridBigCell Grid.Row="0"
                              Grid.Column="0"
                              OuterCell="{Binding Grid[0]}" />
        <controls:GridBigCell Grid.Row="0"
                              Grid.Column="1"
                              OuterCell="{Binding Grid[1]}" />
        <controls:GridBigCell Grid.Row="0"
                              Grid.Column="2"
                              OuterCell="{Binding Grid[2]}" />
        <controls:GridBigCell Grid.Row="1"
                              Grid.Column="0"
                              OuterCell="{Binding Grid[3]}" />
        <controls:GridBigCell Grid.Row="1"
                              Grid.Column="1"
                              OuterCell="{Binding Grid[4]}" />
        <controls:GridBigCell Grid.Row="1"
                              Grid.Column="2"
                              OuterCell="{Binding Grid[5]}" />
        <controls:GridBigCell Grid.Row="2"
                              Grid.Column="0"
                              OuterCell="{Binding Grid[6]}" />
        <controls:GridBigCell Grid.Row="2"
                              Grid.Column="1"
                              OuterCell="{Binding Grid[7]}" />
        <controls:GridBigCell Grid.Row="2"
                              Grid.Column="2"
                              OuterCell="{Binding Grid[8]}" />
    </Grid>

GridBigCell 控件:

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      x:Class="Sudoku.Controls.GridCell"
      x:Name="this">
    ...
//grid definitions
    ...
    <controls:GridCell Grid.Row="0"
                       Grid.Column="0"
                       Cell="{Binding OuterCell[0], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="0"
                       Grid.Column="1"
                       Cell="{Binding OuterCell[1], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="0"
                       Grid.Column="2"
                       Cell="{Binding OuterCell[2], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="1"
                       Grid.Column="0"
                       Cell="{Binding OuterCell[3], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="1"
                       Grid.Column="1"
                       Cell="{Binding OuterCell[4], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="1"
                       Grid.Column="2"
                       Cell="{Binding OuterCell[5], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="2"
                       Grid.Column="0"
                       Cell="{Binding OuterCell[6], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="2"
                       Grid.Column="1"
                       Cell="{Binding OuterCell[7], Source={x:Reference this}}" />
    <controls:GridCell Grid.Row="2"
                       Grid.Column="2"
                       Cell="{Binding OuterCell[8], Source={x:Reference this}}" />
</Grid>
public partial class GridBigCell : Grid
    {
        public static readonly BindableProperty OuterCellProperty = BindableProperty.Create(
            nameof(OuterCell),
            typeof(OuterCell),
            typeof(GridBigCell));

        public OuterCell OuterCell
        {
            get => (OuterCell)GetValue(OuterCellProperty);
            set => SetValue(OuterCellProperty, value);
        }

        public GridBigCell()
        {
            InitializeComponent();
        }
    }

网格单元格:

<Grid xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      x:Class="Sudoku.Controls.GridCell"
      x:Name="this">
    ...
    <Label Grid.ColumnSpan="3"
           Grid.RowSpan="3"
           Text="{Binding Cell.Number, Source={x:Reference this}, Mode=TwoWay}" />
</Grid>
public partial class GridCell : Grid
    {
        public static readonly BindableProperty CellProperty = BindableProperty.Create(
            nameof(Cell),
            typeof(Cell),
            typeof(GridCell));

        public Cell Cell
        {
            get => (Cell)GetValue(CellProperty);
            set => SetValue(CellProperty, value);
        }

        public GridCell()
        {
            InitializeComponent();
        }
    }

编辑:模型:

public class GameGrid : BindableBase
    {
        public OuterCell this[int i]
        {
            get => OuterCells[i];
            set => OuterCells[i] = value;
        }

        public OuterCell[] OuterCells { get; set; }

        public GameGrid()
        {
            OuterCells = new OuterCell[9];
            for (var i = 0; i < 9; i++)
            {
                OuterCells[i] = new OuterCell();
            }
        }
    }

public class Cell : BindableBase
    {
        public int Number { get; set; } = 1;

        public bool IsSelected { get; set; }

        public bool IsInvalid { get; set; }

        public Note[] Notes { get; set; }

        public Cell()
        {
            Notes = new Note[9];
            for (var i = 0; i < 9; i++)
            {
                Notes[i] = new Note(i + 1);
            }
        }
    }

public class OuterCell : BindableBase
    {
        public Cell this[int i]
        {
            get => Cells[i];
            set => Cells[i] = value;
        }

        public Cell[] Cells { get; set; } = new Cell[9];

        public OuterCell()
        {
            for (var i = 0; i < 9; i++)
            {
                Cells[i] = new Cell();
            }
        }
    }

PropertyChanged 由 Fody.PropertyChanged 库处理。

好吧,通过删除 GridBigCell.xaml & cs 并重新创建它设法修复了它。为什么这有效?不知道。