简体   繁体   中英

How to do DataBinding for ControlTemplates in Xamarin.Forms

Disclaimer: I'm new to Xamarin.Forms and Xaml in general

I'm trying to figure out how DataBinding works within templates in Xamarin.Forms.

Xaml:

<ContentPage.Resources>
    <ResourceDictionary>
        <ControlTemplate x:Key="GridItem">
            <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="0" ColumnSpacing="0" RowSpacing="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="1*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*" />
                </Grid.ColumnDefinitions>

                <ContentView Grid.Row="0" Grid.Column="0" BackgroundColor="Red" VerticalOptions="FillAndExpand" Padding="15">
                    <Image Source="{TemplateBinding ImageSource}" BackgroundColor="Red" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
                </ContentView>
              <Label Grid.Row="1" Grid.Column="0" Text="{TemplateBinding LabelText}" FontSize="Large" TextColor="White" BackgroundColor="#8B0000" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
            </Grid>
        </ControlTemplate>
    </ResourceDictionary>
</ContentPage.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*" />
        <RowDefinition Height="1*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" />
        <ColumnDefinition Width="1*" />
    </Grid.ColumnDefinitions>

    <ContentView x:Name="randomButton1" ControlTemplate="{StaticResource GridItem}"  Grid.Row="0" Grid.Column="0" />
    <ContentView x:Name="randomButton2" ControlTemplate="{StaticResource GridItem}"  Grid.Row="0" Grid.Column="1" />
</Grid>

C# Code behind using Xamarin.Forms;

namespace TestApp.XForms
{
    public partial class Page1 : ContentPage
    {
        private readonly MainButtonViewModel[] buttons;

        public Page1()
        {
            InitializeComponent();

            randomButton1.BindingContext = new MainButtonViewModel("some text1", "someimage1.png");
            randomButton2.BindingContext = new MainButtonViewModel("some text2", "someimage2.png");
        }
    }

    public class MainButtonViewModel : BindableObject
    {
        private string labelText;
        public string LabelText
        {
            get { return labelText; }
            set
            {
                labelText = value;
                OnPropertyChanged();
            }
        }

        private string imageSource;
        public string ImageSource
        {
            get { return imageSource; }
            set
            {
                imageSource = value;
                OnPropertyChanged();
            }
        }

        public MainButtonViewModel()
        {
        }
        public MainButtonViewModel(string text, string imageLocation)
        {
            LabelText = text;
            ImageSource = imageLocation;
        }
    }
}

So my templates seem to work. I see 2 red blocks. But none of the bindings seem to have worked. Everything is empty: 在此处输入图片说明

How can I get the data binding to work?

Your view model doesn't support INotifyPropertyChanged . You could use Xamarin.Forms class:

public class SomeViewModel : BindableObject

And then you could notify UI, that some property has been changed:

        private string _someStringProperty;
        public string SomeStringProperty
        {
            get { return _someStringProperty; }
            set
            {
                _someStringProperty = value;
                OnPropertyChanged();
            }
        }

Also will be helpful Binding from ControlTemplate .

When you use ControlTemplate it requires TemplateBinding for BindingContext , otherwise it won't have any BindingContext itself. You can use DataTemplate without setting BindingContext , it inherits parent's BindingContext itself.

ie:

<ControlTemplate x:Key="yourTemplate" BindingContext="{TemplateBinding BindingContext}">
  <Grid>
    <!--Your Template-->
  </Grid>
</ControlTemplate>

<DataTemplate x:Key="yourTemplate">
  <Grid>
    <!--Your Template-->
  </Grid>
</DataTemplate>

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