Observable Collection - Binding Failure : Property Not Found

Rakesh Jain 41 Reputation points
2021-03-17T11:23:04.577+00:00

I am using Observable Collection to populate cells in a Grid. Collection builds okay but fails to bind to properties. I have tried many alternatives: Obviously, I am doing something wrong. My code is below. I am using Visual Studio Community 2019 for development. Output window message from Visual Studio is noted in View Code below.

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"
             x:Class="Navkar.Views.MatrixPage"
             Title="AanuPurvi - Navkar Matrix">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness"
        iOS="1,20,1,1"
        Android="1"
        WinPhone="1"/>
    </ContentPage.Padding>
    <StackLayout>
        <!-- Header -->
        <Frame BackgroundColor="#2196F3" Padding="1" CornerRadius="0">
            <Image x:Name="matrixBanner" Source="apbanner" VerticalOptions="Center" HorizontalOptions="Center">
                <Image.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnBannerImageTapped" NumberOfTapsRequired="2"/>
                </Image.GestureRecognizers>
            </Image>
        </Frame>
        <!-- Messages -->
        <StackLayout x:Name="matrixLabels" Orientation="Horizontal">
            <Label x:Name="matrixLevelLabel" Text="{Binding MatrixNumber, StringFormat='{0}'}" BackgroundColor="LightBlue" HorizontalTextAlignment="Start" FontSize="Large" FontAttributes="Bold" Padding="8,0,8,0"/>
            <Label Text="{Binding NavkarPrayer}" TextColor="{Binding PrayerColor}" BackgroundColor="LightBlue" HorizontalOptions="FillAndExpand" FontSize="Large" FontAttributes="Bold" Padding="8,0,8,0" />
        </StackLayout>
        <ScrollView VerticalOptions="FillAndExpand">
            <StackLayout x:Name="matrixStack" HorizontalOptions="FillAndExpand">
                <Grid x:Name="matrixGrid" RowSpacing="1" ColumnSpacing="1" Padding="1" HorizontalOptions="CenterAndExpand">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                </Grid>
                <StackLayout x:Name="matrixNav" Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
                    <Button x:Name="btnMatrixStyle" Text="{Binding StyleCommandText}" StyleId="0" CommandParameter="1" Command="{Binding StyleCommand}"/>
                    <Button x:Name="btnPrev" Text="Prev" StyleId="0" CommandParameter="-1" Command="{Binding PrevCommand}"/>
                    <Button x:Name="btnReset" Text="Reset" StyleId="1" CommandParameter="0" Command="{Binding ResetCommand}"/>
                    <Button x:Name="btnNext" Text="Next" StyleId="2" CommandParameter="1" Command="{Binding NextCommand}"/>
                </StackLayout>
                <StackLayout x:Name="matrixFooter">
                    <Label FontSize="16" Padding="8,10,8,0">
                        <Label.FormattedText>
                            <FormattedString>
                                <FormattedString.Spans>
                                    <Span Text="Starting in the first row from left to right press each letter and recite corresponding Navkar Line.&#10;"/>
                                    <Span Text="www.mynarada.ca" FontAttributes="Bold"/>
                                </FormattedString.Spans>
                            </FormattedString>
                        </Label.FormattedText>
                    </Label>
                </StackLayout>
            </StackLayout>
        </ScrollView>
    </StackLayout>
</ContentPage>

Model

using System.Collections.ObjectModel;
using Xamarin.Forms;

namespace Navkar.Models
{
    public class MatrixCell
    {
        public string Text { get; set; }
        public Color TextColor { get; set; }
        public int Row { get; set; }
        public int Column { get; set; }
        public string StyleId { get; set; }
        public int TabIndex { get; set; }
        public Color BackgroundColor { get; set; }
    }

    public class Matrix : ObservableCollection<MatrixCell> { }

    public class MatrixModelObj
    {
        public Matrix MatrixCellItems { get; set; }
        public MatrixModelObj()
        {
            MatrixCellItems = new Matrix();
        }
    }
}

ViewModel

using Navkar.Models;
using Navkar.ViewModels.Helpers;
using System;
using Xamarin.Forms;

namespace Navkar.ViewModels
{
    public class MatrixViewModel
    {
        readonly App app = Application.Current as App;
        private int _MatrixNumber;
        private string _MatrixStyle;
        private MatrixModelObj MatrixData;
        public MatrixViewModel(MatrixModelObj _MatrixModel)
        {
            _MatrixNumber = app.MatrixNumber < 1 ? 1 : app.MatrixNumber;
            _MatrixStyle = app.MatrixStyle ?? "0";
            app.MatrixNumber = _MatrixNumber;
            app.MatrixStyle = _MatrixStyle;

            MatrixData = _MatrixModel;
            GetMatrix();
        }
        public Matrix Matrix
        {
            get => this.MatrixData.MatrixCellItems;
            private set
            {
                this.MatrixData.MatrixCellItems = value;
            }
        }
        #region Matrix
        private void GetMatrix()
        {
            int matrixRow;
            int matrixCol;
            int matrixCellNumber;
            int arrIndex;
            string matrixCellText;
            string navkarLine;

            //MatrixModel = new MatrixModelObj();
            //_Matrix = new Matrix();
            //if (_Matrix.Count > 0) { _Matrix.Clear(); }
            if (MatrixData.MatrixCellItems.Count > 0) { MatrixData.MatrixCellItems.Clear(); }
            for (matrixRow = 0; matrixRow < 6; matrixRow++)
            {
                for (matrixCol = 0; matrixCol < 5; matrixCol++)
                {
                    navkarLine = Helper.GetNavkarLine(_MatrixNumber, matrixRow, matrixCol);
                    arrIndex = Convert.ToInt32(navkarLine);
                    matrixCellNumber = (matrixRow * 5) + matrixCol + 1;
                    matrixCellText = (_MatrixStyle == "1") ? navkarLine : Helper.HindiNumbers[arrIndex];
                    //_Matrix.Add(new MatrixCell()
                    MatrixData.MatrixCellItems.Add(new MatrixCell()
                    {
                        Text = matrixCellText,
                        TextColor = Helper.PrayerColor[arrIndex],
                        Row = matrixRow,
                        Column = matrixCol,
                        StyleId = navkarLine,
                        TabIndex = matrixCellNumber
                    });
                }
            }
        }
        #endregion
    }
}

View

using Navkar.ViewModels;
using Navkar.Models;
using System;
using System.Diagnostics;
using Xamarin.Forms;

namespace Navkar.Views
{
    public partial class MatrixPage : ContentPage
    {
        private readonly ButtonViewModel _ButtonViewModel = new ButtonViewModel();
        private readonly MatrixModelObj _MatrixModelObj = new MatrixModelObj();
        private readonly Matrix _Matrix;
        public MatrixPage()
        {
            InitializeComponent();
            BindingContext = _ButtonViewModel;
            MatrixViewModel _MatrixViewModel = new MatrixViewModel(_MatrixModelObj);
            _Matrix = _MatrixViewModel.Matrix;
            DisplayMatrix();
        }
        private void DisplayMatrix()
        {
            for (int index = 0; index < _Matrix.Count; index++)
            {

                Button button = new Button
                {   
                    #region - Working
                    Text = _Matrix[index].Text,
                    TextColor = _Matrix[index].TextColor,
                    CommandParameter = _Matrix[index].StyleId,
                    FontSize = Device.GetNamedSize(NamedSize.Title, typeof(Button)),
                    FontAttributes = FontAttributes.Bold,
                    BackgroundColor = Color.SteelBlue,
                    CornerRadius = 10
                    #endregion
                };

                #region - Binding not working
                // Output Message: [0:] Binding: '{Binding TextColor}'
                // property not found on 'Navkar.Models.Matrix', target property:
                // 'Xamarin.Forms.Button.TextColor'
                //button.BindingContext = _Matrix;
                //button.SetBinding(Button.TextProperty, "{Binding Text}");
                //button.SetBinding(Button.TextColorProperty, "{Binding TextColor}");
                //button.SetBinding(TabIndexProperty, "{Binding TabIndex}");
                //button.SetBinding(Button.CommandParameterProperty, "{Binding StyleId}");
                #endregion
                button.SetBinding(Button.CommandProperty, "PrayerCommand");
                matrixGrid.Children.Add(button, _Matrix[index].Column, _Matrix[index].Row);
            }
        }
    }
Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,294 questions
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 68,571 Reputation points Microsoft Vendor
    2021-03-18T09:38:36.007+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    I notice you bind the ButtonViewModel with BindingContext = _ButtonViewModel;, all of the Button binding property should be put in the ButtonViewModel like following code.

       public class ButtonViewModel  
           {  
               public ICommand PrayerCommand { protected set; get; }  
               public string ButtonText { get; set; }  
         
               public Color BtnTextColor { get; set; }  
               public ButtonViewModel()  
               {  
                   PrayerCommand = new Command(async (key) => {  
                       Console.WriteLine("execute=============");  
         
         
                   });  
                   ButtonText = "test1";  
         
                   BtnTextColor = Color.Green;  
               }  
           }  
    

    I test with following binding value, it worked as normal.

       button.SetBinding(Button.TextProperty, "ButtonText");  
       button.SetBinding(Button.TextColorProperty, "BtnTextColor");  
       button.SetBinding(Button.CommandProperty, "PrayerCommand");  
    

    79122-image.png

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful