Jason Jason - 2 months ago 15
C# Question

Using a ContentPresenter for a custom control (Thumb)

I created a custom control that allows for drag using the DragDelta of the Thumb control. I want to be able to insert a Shape, Image or TextBlock inside the custom control ContentPresenter.

CustomControl.xaml (Thumb)

<Thumb x:Class="StackOverflow.CustomControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Thumb.Template>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Thumb.Template>
</Thumb>


MainWindow.xaml

<Window x:Class="StackOverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackOverflow">
<local:CustomControl>
<!--Shape, Image or TextBlock-->
</local:CustomControl>
</Window>

Answer

Since the Content property is Object, you can put anything in there that will go in a ContentControl: Visual tree elements, strings, a viewmodel with an implicit DataTemplate (pretty farfetched in this particular case, but it's the principle of the thing) -- you name it.

MyThumb.xaml

<Thumb 
    x:Class="ThumbTest.MyThumb"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:thumb="clr-namespace:ThumbTest"
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="300"
    >
    <Thumb.Template>
        <ControlTemplate TargetType="thumb:MyThumb">
            <ContentPresenter 
                />
        </ControlTemplate>
    </Thumb.Template>
</Thumb>

VS is giving me a blue squiggle under <Thumb... in the XAML because the TargetType of the ControlTemplate doesn't match, but it builds and works fine. This change to the template will get rid of that:

<Thumb.Template>
    <ControlTemplate TargetType="thumb:MyThumb">
        <ContentControl
            Content="{Binding Content, RelativeSource={RelativeSource AncestorType=thumb:MyThumb}}"
            />
    </ControlTemplate>
</Thumb.Template>

MyThumb.xaml.cs

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;

namespace ThumbTest
{
    [ContentProperty("Content")]
    public partial class MyThumb : Thumb
    {
        public MyThumb()
        {
            InitializeComponent();
        }

        #region Content Property
        public Object Content
        {
            get { return (Object)GetValue(ContentProperty); }
            set { SetValue(ContentProperty, value); }
        }

        public static readonly DependencyProperty ContentProperty =
            DependencyProperty.Register("Content", typeof(Object), typeof(MyThumb),
                new PropertyMetadata(null));
        #endregion Content Property
    }
}