question

RakeshJain-7434 avatar image
0 Votes"
RakeshJain-7434 asked RakeshJain-7434 action

Observable Collection - Binding Failure : Property Not Found

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);
             }
         }
     }
dotnet-xamarin
· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If you add Command binding for button in the background code, you can use button.Clicked event directly.

0 Votes 0 ·

Hello LeonLu:

Binding failure is happening for all properties of button: Text, TextColor, TabIndex, StyleId. The problem I am having is binding properties of the buttons added as child in the grid.

I also have ButtonViewModel which binds properties of other controls and buttons in the view.

0 Votes 0 ·

1 Answer

LeonLu-MSFT avatar image
1 Vote"
LeonLu-MSFT answered RakeshJain-7434 commented

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.



image.png (107.5 KiB)
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I made changes as noted below:

  1. Added Command property to the model

  2. Moved the ButtonViewModel code to MatrixViewModel.

  3. Used a template defined in APP.XAML to populate the Matrix with Observable Collection.

It worked. Your suggestion to put all of the Button Properties in same model was helpful.

Thanks @LeonLu-MSFT



0 Votes 0 ·