Boris
Boris

Reputation: 10234

WPF: How to data bind an object to an element and apply a data template through code?

I have created a class LeagueMatch.

public class LeagueMatch
{
    public string Home
    {
        get { return home; }
        set { home = value; }
    }

    public string Visitor
    {
        get { return visitor; }
        set { visitor = value; }
    }

    private string home;
    private string visitor;

    public LeagueMatch()
    {
    }
}

Next, I have defined a datatemplate resource for LeagueMatch objects in XAML:

<DataTemplate x:Key="MatchTemplate" DataType="{x:Type entities:LeagueMatch}">
    <Grid Name="MatchGrid" Width="140" Height="50" Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Text="{Binding Home}" />
        <TextBlock Grid.Row="1" Text="- vs -" />
        <TextBlock Grid.Row="2" Text="{Binding Visitor}" />
    </Grid>    
</DataTemplate>

In the XAML code-behind, I want to create a ContentPresenter object and to set it's data binding to a previously initialized LeagueMatch object and apply the defined data template. How is that supposed to be done? Thanks.

Solution

LeagueMatch match = new LeagueMatch("A team", "B team");

ContentPresenter contentPresenter = new ContentPresenter();
contentPresenter.ContentTemplate = this.FindResource("MatchTemplate") as DataTemplate;
Binding binding = new Binding();
binding.Source = match;
contentPresenter.SetBinding(ContentPresenter.ContentProperty, binding);

matchSlot.Children.Clear();
matchSlot.Children.Add(contentPresenter);

Upvotes: 1

Views: 1725

Answers (2)

Femaref
Femaref

Reputation: 61427

<ContentPresenter ContentTemplate="{StaticResource yourTemplate}" 
                   DataContext="{Binding Match}"/>

In code-behind:

ContentPresenter c = new ContentPresenter();
c.ContentTemplate = FindResource("yourTemplate");
Binding b = new Binding();
b.Path = "Match"; // if the object is a property on someObject, otherwise leave it out.
b.Source = someObject;

c.SetBinding(ContentPresenter.ContentProperty, b);

Implementing INotifyPropertyChanged

public class Sample : INotifyPropertyChanged
{
  private string sampleField = "";

  public string SampleProperty
  {
    get { return sampleField; }
    set
    {
       sampleField = value;
       RaisePropertyChanged("SampleProperty");
    }
  }

  #region INotifyPropertyChanged

  public event PropertyChangedEventHandler PropertyChanged;

  private void RaisePropertyChanged(string property)
  {
     var handler = PropertyChanged;
     if(handler != null)
        handler(this, new PropertyChangedEventArgs(property));
  }
}

Be sure to change your properties only by assigning to the property so the event gets executed. The binding engine is listening to those events to refresh the binding.

Upvotes: 2

John Bowen
John Bowen

Reputation: 24453

You need to bind to the Content property on the ContentPresenter, not DataContext, to apply the template to your data:

contentPresenter.SetBinding(ContentPresenter.ContentProperty, binding);

Upvotes: 0

Related Questions