none
Help with data binding in a ControlTemplate please!! RRS feed

  • Question

  • Hello gentlemen,

    I have a button with a controltemplate with a grid look, and inside this grid I want to get the data from a class called Person its property "Name" that returns "My Name is abc". (This string is assigned in the constructor)

    In the following code it does not display "My Name is abc" on the grid, I really appreciate if anyone can give some specific code to make it! thanks in advance!!

     

    The code is here

    Code Block

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:Imperial">


      <Style x:Key="styleCanvasInfo">
        <Setter Property="Button.Template">
          <Setter.Value>
            <ControlTemplate>


        <Grid>
         <Grid.RowDefinitions>
          <RowDefinition />
          <RowDefinition />
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition />
         </Grid.ColumnDefinitions>
         <Grid.Background>
          <LinearGradientBrush>
           <LinearGradientBrush.GradientStops>
            <GradientStop Color="LightBlue" Offset="0" />
            <GradientStop Color="WhiteSmoke" Offset="1" />
           </LinearGradientBrush.GradientStops>
          </LinearGradientBrush>
         </Grid.Background>
         <TextBlock Grid.Row="0" Grid.Column="0" Text="Row1" />
         <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Name}"/>
         <TextBlock Grid.Row="1" Grid.Column="0" Text="Row2" />
         <TextBlock Grid.Row="1" Grid.Column="1" Text="some text" />
         </Grid>


       </ControlTemplate>
      </Setter.Value>
     </Setter>
    </Style>

      <Button
        x:Key="buttonTopLeft"
        Canvas.Top="100"
        Canvas.Left="100"
        Style="{StaticResource styleCanvasInfo}"/>

     </ResourceDictionary>

     

     

    This is the Person.cs class

    Code Block

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace Imperial

    {
       public class Person
        {
           private string _name;

           public string Name
           {
               get
               {
                   return _name;
               }
           }


           public Person()
           {
               _name= "My Name is abc";
           }


        }
    }

     

     

    Thursday, January 17, 2008 8:11 PM

Answers

  • It's not a good idea to bind to data object in ControlTemplate, the recommended way is to use DataTemplate, if you really need data binding in ControlTemplate:

    Code Block
    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Button>
            <Button.Content>
                <x:Type TypeName="Visual"/>
            </Button.Content>
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <TextBlock Text="{Binding Path=Content.Name, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </Page>

    But I still recommend using the following method instead:

    Code Block
    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Button>
            <Button.Content>
                <x:Type TypeName="Visual"/>
            </Button.Content>
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <ContentPresenter ContentSource="Content"/>
                    </Grid>
                </ControlTemplate>
            </Button.Template>
            <Button.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </Button.ContentTemplate>
        </Button>
    </Page>


    Hope this helps

    Monday, January 21, 2008 7:46 AM

All replies

  • Well it all depends on what control you are setting this template to.

     

    If your control is a ContentControl, you could do this I believe:

     

    "{TemplateBinding (Content).(localStick out tongueerson.Name)}"

     

    --if you're setting it's content to your Person's class instance.  Note: set TargetType="ContentControl" on your ControlTemplate

     

    Otherwise, you need to make a custom control with a custom DependencyProperty that you could bind to.  So you you created a class called PersonControl, set TargetType to "PersonControl" on your ControlTemplate and your binding would be:

     

    "{TemplateBinding (MyPerson).(Name)}"  --where MyPerson is your new DP.

     

    Another alternate method I've used when sometimes this doesn't work is to use a binding's RelativeSource, so you could:

     

    "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=localStick out tongueersonControl}, Path=MyPerson}}"

     

    or

     

    "{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentControl}, Path=(Content).(localStick out tongueerson.Name)}}"

     

    One of those should work for you.

     

    -PS-these stupid Emoticons are a colon followed by a P, this is probably the most retarded thing about MSDN forums

    Thursday, January 17, 2008 11:12 PM
  • Hi Jonathan!

    thanks for your reply man!!

     

    by the way the control that I am using is a button as the following.

     

    thank you!

     

    Code Block

    <Button
        x:Key="buttonTopLeft"
        Canvas.Top="100"
        Canvas.Left="100"
        Style="{StaticResource styleCanvasInfo}"/>

     

     

    Friday, January 18, 2008 4:11 PM
  • It's not a good idea to bind to data object in ControlTemplate, the recommended way is to use DataTemplate, if you really need data binding in ControlTemplate:

    Code Block
    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Button>
            <Button.Content>
                <x:Type TypeName="Visual"/>
            </Button.Content>
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <TextBlock Text="{Binding Path=Content.Name, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </Page>

    But I still recommend using the following method instead:

    Code Block
    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Button>
            <Button.Content>
                <x:Type TypeName="Visual"/>
            </Button.Content>
            <Button.Template>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid>
                        <ContentPresenter ContentSource="Content"/>
                    </Grid>
                </ControlTemplate>
            </Button.Template>
            <Button.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </Button.ContentTemplate>
        </Button>
    </Page>


    Hope this helps

    Monday, January 21, 2008 7:46 AM