简体   繁体   中英

Adding a C# template to XAML code. How can I do the binding?

I have a C# class like this used in my application. It is a grid with four buttons.

If I view two buttons the output is:

在此处输入图片说明

If I view three buttons the output is:

在此处输入图片说明

Note that as the btn2 and btn3 are identical I can find now reason why two works and three does not:

public class PracticeButtons : Grid
{
    public PracticeButtons()
    {
        this.Padding = new Thickness(20, 0, 20, 0);

        var btn1 = new CardButtonTemplate()
        {
            ButtonBackgroundColor = (Color)Application.Current.Resources["IosRed"],
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            VerticalOptions = LayoutOptions.Center
        };
        btn1.SetBinding(CardButtonTemplate.TapCommandProperty, new Binding("ABtnCmd"));
        btn1.SetBinding(CardButtonTemplate.TextTopProperty, new Binding("ABtnTitleLabelTop"));
        btn1.SetBinding(CardButtonTemplate.TextBtmProperty, new Binding("ABtnTitleLabelBtm"));

        var btn2 = new CardButtonTemplate()
        {
            ButtonBackgroundColor = (Color)Application.Current.Resources["IosOrange"],
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            VerticalOptions = LayoutOptions.Center
        };
        btn2.SetBinding(CardButtonTemplate.TapCommandProperty, new Binding("BBtnCmd"));
        btn2.SetBinding(CardButtonTemplate.TextTopProperty, new Binding("BBtnTitleLabelTop"));
        btn2.SetBinding(CardButtonTemplate.TextBtmProperty, new Binding("BBtnTitleLabelBtm"));

        var btn3 = new CardButtonTemplate()
        {
            ButtonBackgroundColor = (Color)Application.Current.Resources["IosOrange"],
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            VerticalOptions = LayoutOptions.Center
        };
        btn3.SetBinding(CardButtonTemplate.TapCommandProperty, new Binding("BBtnCmd", source: this));
        btn3.SetBinding(CardButtonTemplate.TextTopProperty, new Binding("BBtnTitleLabelTop", source: this));
        btn3.SetBinding(CardButtonTemplate.TextBtmProperty, new Binding("BBtnTitleLabelBtm", source: this));

        this.Children.Add(btn1, 0, 0);
        this.Children.Add(btn2, 1, 0);
        this.Children.Add(btn3, 2, 0); // commented when viewing 2 buttons
    }
}

UPDATE

Please remove "source:this" from btn3 set binding method.

btn3.SetBinding(CardButtonTemplate.TextTopProperty, new Binding("BBtnTitleLabelTop"));

We can bind whole BindingContext object using "."

<Grid>
   <!--<buttons:CardPracticeButtons />-->
   <studycards:PracticeButtons BindingContext="{Binding .}"/>
</Grid>

PracticeButtons

using Xamarin.Forms;
namespace StudyCards
{
    public class PracticeButtons : Grid
    {
        public PracticeButtons()
        {
            var btn1 = new CardTemplate() { };
            btn1.SetBinding(CardTemplate.TapCommandProperty, "ABtnCmd");
            btn1.SetBinding(CardTemplate.TextAProperty, "ABtnTitleLabelA");
            btn1.SetBinding(CardTemplate.TextBProperty, "ABtnTitleLabelB");
            this.Children.Add(btn1, 0, 0);
        }
    }
}

EDIT

I have written below example.

Home.xaml

<Grid>
            <App1:PracticeButtons x:Name="Test" BindingContext="{Binding .}"/>
        </Grid>

Home.xaml.cs

public Home(){
           InitializeComponent();

            viewModel = new ViewModel();

            BindingContext = viewModel;
}

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
    {
private string _ABtnTitleLabelA;
        
        public string ABtnTitleLabelA
        {
            get => _ABtnTitleLabelA;
            set
            {
                _ABtnTitleLabelA = value;
                OnPropertyChanged();
            }
        }

public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var propertyChanged = PropertyChanged;
            propertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

public ViewModel()
        {
           
            _ABtnTitleLabelA = "Testttttt";
            
        }
}

PracticeButton.cs

public class PracticeButtons : Grid
    {
       
        public PracticeButtons()
        {
            var btn1 = new CardButtonTemplate();
            btn1.SetBinding(CardButtonTemplate.TextBProperty, "ABtnTitleLabelA");
            this.Children.Add(btn1, 0, 0);
        }
    }

CardButtonTemplate.cs

public class CardButtonTemplate : StackLayout
    {
        public CardButtonTemplate()
        {
            this.HorizontalOptions = LayoutOptions.Center;
            this.VerticalOptions = LayoutOptions.Center;

            var TL = new Label()
            {
                HorizontalOptions = LayoutOptions.CenterAndExpand,
                VerticalOptions = LayoutOptions.Start,
                HorizontalTextAlignment = TextAlignment.Center,
            };
            TL.SetBinding(Label.TextProperty, new Binding("TextB", source: this));
            

            this.Children.Add(TL);
            
        }

        
        public static readonly BindableProperty TextBProperty = BindableProperty.Create(nameof(TextB),
            typeof(string), typeof(Frame), default(string), propertyChanged: TextBPropertyPropertyChanged);
        

        
        public string TextB { get => (string)GetValue(TextBProperty); set => SetValue(TextBProperty, value); }
        
        private static void TextBPropertyPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            //if (!string.IsNullOrEmpty((string)newValue))
            //{
            //    CardButtonTemplate cardButtonTemplate = bindable as CardButtonTemplate;
            //    cardButtonTemplate.firstRow.Height = 30;
            //    cardButtonTemplate.textA.VerticalOptions = LayoutOptions.End;

            //}
            //else
            //{
            //    CardButtonTemplate cardButtonTemplate = bindable as CardButtonTemplate;
            //}
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM