Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'

by Kristian Wilson   Last Updated October 15, 2019 22:26 PM - source

I wonder if anyone can help. I have been banging my head against this problem for half a day now, I must be doing something wrong. I have a custom control with a number of dependency properties.

[TemplatePart(Name = InformationBubble.InformationBubbleTitlePart, Type = typeof(TextBlock))]
[TemplatePart(Name = InformationBubble.InformationBubbleProductImagePart, Type=typeof(Image))]

public class InformationBubble : Control 
{
    #region Template Parts Name Constants

    /// <summary>
    /// Name constant for the Information Bubble Title Part
    /// </summary>
    public const string InformationBubbleTitlePart = "InformationBubbleTitleText";

    /// <summary>
    /// Name constant for the Information Bubble Product Image Part
    /// </summary>
    public const string InformationBubbleProductImagePart = "InformationBubbleProductImage";

    #endregion

    #region TemplateParts

    private TextBlock _Title;

    internal TextBlock Title
    {
        get { return _Title; }
        private set
        {
            _Title = value;

            if (_Title != null)
            {
                _Title.Text = this.ProductTitleText;       
            }
        }
    }

    private Image _ProductImage;

    internal Image ProductImage
    {
        get { return _ProductImage; }
        private set
        {
            _ProductImage = value;

            if (_ProductImage != null)
            {
                _ProductImage.Source = this.ProductImageSource;
            }
        }
    }

    #endregion

    #region Public String Product Title 

    // Dependency properties declaration
    public static readonly DependencyProperty ProductTitleProperty = DependencyProperty.Register(
        "ProductTitle",
        typeof(string),
        typeof(InformationBubble),
        new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnProductTitleChanged)));

    public static void OnProductTitleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        InformationBubble iBubble = sender as InformationBubble;

        if (iBubble.Title != null)
        {
            iBubble.Title.Text = e.NewValue as string;
        }
    }

    public string ProductTitleText
    {
        get { return GetValue(ProductTitleProperty) as string; }
        set { SetValue(ProductTitleProperty, value); }
    }

    #endregion

    #region Public Image Source Product Image

    public static readonly DependencyProperty ProductImageSourceProperty = DependencyProperty.Register(
        "ProductImageSource",
        typeof(ImageSource),
        typeof(InformationBubble),
        new PropertyMetadata(null, new PropertyChangedCallback(OnProductImageSourceChanged)));

    public static void OnProductImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        InformationBubble iBubble = sender as InformationBubble;

        if (iBubble.ProductImage != null)
        {
            iBubble.ProductImage.Source = e.NewValue as ImageSource;
        }
    }

    public ImageSource ProductImageSource
    {
        get { return GetValue(ProductImageSourceProperty) as ImageSource; }
        set { SetValue(ProductImageSourceProperty, value); }
    }

    #endregion

    public InformationBubble()
    {
         this.DefaultStyleKey = typeof(InformationBubble);
    }

    #region Overrides

    public override void OnApplyTemplate()
    {       
        base.OnApplyTemplate();

        Title = GetTemplateChild(InformationBubble.InformationBubbleTitlePart) as TextBlock;
        ProductImage = GetTemplateChild(InformationBubble.InformationBubbleProductImagePart) as Image;
    }

    #endregion

    #region Private Methods

    private void GoToState(string stateName, bool useTransitions)
    {
        VisualStateManager.GoToState(this, stateName, useTransitions);
    }

    #endregion
}

Now if I use this control somewhere in my xaml it works if I do this:

<controls:InformationBubble 
        ProductImageSource="{Binding SelectedItem.NormalImageSource}"
        ProductTitleText="Test Title"
        "/>

But if I try and data bind the product title text to the title property of the SelectedItem object in my ViewModel:

<controls:InformationBubble 
            ProductImageSource="{Binding SelectedItem.NormalImageSource}"
            ProductTitleText="{Binding SelectedItem.Title, Mode=TwoWay"
            "/>

I get Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'. The text property of a TextBlock is a DependencyProperty so I must be missing something obvious here.

Any help or insight is much appreciated.

Kris



Answers 1


Could it be that the name of the property is wrong. Should the "ProductTitle" in the code below perhaps be "ProductTitleText"?

public static readonly DependencyProperty ProductTitleProperty = DependencyProperty.Register(
    "ProductTitle",  // "ProductTitleText" ?
    typeof(string),
    typeof(InformationBubble),
    new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnProductTitleChanged)));

I imagine that when you use a string constant, then WPF uses reflection to access the property "public string ProductTitleText" directly. The DependencyProperty is ignored, as the name of the property do not match ("ProductTitle" vs. "ProductTitleText").

So for the title you have a dependency property called "ProductTitle" and a (string) property called "ProductTitleText". For the ProductImage you have a dependency property called "ProductImageSource" and a property (of type ImageSource) also called "ProductImageSource".

Does it make sense?

Ole Tolshave
Ole Tolshave
May 23, 2011 16:42 PM

Related Questions


TabItem Clicked

Updated May 22, 2019 04:26 AM




WPF Format Binding not working

Updated March 08, 2017 01:26 AM