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

时间:2019-07-18 17:20:50

标签: c# xaml xamarin.forms custom-controls xaml-binding

我正在尝试创建一个简单的(数独)网格,该网格基本上由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();
        }
    }

GridCell:

<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库处理。

1 个答案:

答案 0 :(得分:0)

好吧,设法通过删除GridBigCell.xaml&cs并重新创建来对其进行修复。为什么这样做有效?不知道。