views:

126

answers:

2

Hi all,

I am new to using the ControlTemplate. I am writing my first control but I am having (what seems to me) a very strange issue.

Any dependency properties that I make that I TemplateBind to work, but any properties from the .NET framework objects i.e. the Content property of a ContentControl or the Items property of an ItemsControl does not get populated at runtime.

I am sure I am missing something... Just what it is I dont know...

An example of the code is below:

The class is very simple at the moment:

public class Title : ContentControl
{
}

And the Template is:

<Style TargetType="{x:Type UI:Title}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type UI:Title}">
                <TextBlock Text="{TemplateBinding Content}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The base ContentControl class is the .NET class located in the System.Windows.Controls.Control namespace.

Thanks,

Adam

A: 

You may need to implement the INotifyPropertyChanged interface on your objects and INotifyCollectionChanged on your collections.

automatic
+1  A: 

I believe if you'd like to override where the Content is placed you can do that using a ContentPresenter.

<Style TargetType="{x:Type UI:Title}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type UI:Title}">
                <Label>
                    <ContentPresenter />
                </Label>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Note I've also changed from a TextBlock to a Label as I believe the TextBlock.Text property will not accept everything from ContentControl.Content. Here is an example I put together that works as intended:

<Window x:Class="ContentControlTest.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ContentControlTest"
        Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type local:Title}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:Title}">
                        <Button>
                            <ContentPresenter />
                        </Button>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <local:Title>
        <TextBlock Text="Happy Days!" />
    </local:Title>
</Window>
sixlettervariables
I have just tried your suggestion. It does not seem to work... I have done a bit more investigation and it seems that no matter when I set the property it does not get displayed but if I put a value in the constructor of the Title class assigning a value to the Content property then it is displayed...
Any ideas? Thank you for your feedback.
I've updated with a working example.
sixlettervariables
Does that not break the rules of making your own controls? From what I understand I should not have to place any controls onto my window as the style defined in General.xaml will handle it. I want to TemplateBind to the Content property of my Title class so whenever that property gets changed it will update in my UI. Thanks for your feedback again.
So what you really want is the title control's content to be bound to some text value? TemplateBinding is not what you're looking for in that case as well.
sixlettervariables
As a side-note, you ARE supposed to place controls on the Window. I'm not entirely sure what you meant by "break the rules". Styles are used to create or change the visual representation of an element.
sixlettervariables
Ok. Im going to have to go away and do some more reading on this. Thanks for your help. Ill come back when I understand what this is all about :)
Its been a while and I am doing a clean up. Yes you are right. Template binding is not what I am looking for in this case. As it is a content control I can use a content presenter to display the content properties value as shown in your example code. Thanks for your help.