locked
Data binding to RangeBase Value property doesn't seem to work

    Question

  • I'm creating a knob-like control and I am having some trouble getting a data binding to work. I created the control inheriting from RangeBase, and set the RenderTransform on the knob 'head' piece to a RotateTransform, and am trying to bind its angle to the 'Value' property of the control (ideally through some sort of transfer function so that the value range isn't stuck -180 to 180, but for now, I'd settle for a knob that reads in degrees), but it doesn't seem to be working (Bindings of other things, like colors and such, seem to work). I created a stripped down version of the control to illustrate the problem:

    CustomControl.h:

    #pragma once
    
    namespace Repro2
    {
    	public ref class CustomControl sealed : public Windows::UI::Xaml::Controls::Primitives::RangeBase
    	{
    	public:
    		CustomControl();
    	};
    }

    Generic.xaml:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Repro2">
    
        <Style TargetType="local:CustomControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:CustomControl">
                        <Border
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                            <Border.RenderTransform>
                                <RotateTransform Angle="{TemplateBinding Value}" />
                            </Border.RenderTransform>
    
                            <TextBlock Foreground="Green" Text="I SHOULD BE SIDEWAYS" />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

    Instantiated in MainPage.xaml like this:

    <local:CustomControl Value="90" Maximum="180" Minimum="-180" Background="DarkRed" Width="500" Height="500" />
    

    Other than that, I haven't modified the 'Blank XAML app' VS2013 template plus add item->Templated Control.

    I would expect the control to show up sideways, as it does when I exchange the {TemplateBinding Value} for "90", but instead it shows up unrotated. It is DarkRed, so the binding for "Background" seems to be working, but the "Value" one isn't.

    Any help would be greatly appreciated.


    • Edited by MagusOTB Tuesday, February 04, 2014 3:13 AM Edited xaml for local:CustomControl (initially, it lacked Maximum and Minimum
    Sunday, January 26, 2014 9:53 PM

Answers

  • Try switching out the TemplateBinding to instead use the following syntax:
    <RotateTransform Angle="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    • Marked as answer by MagusOTB Monday, February 17, 2014 11:53 PM
    Monday, February 10, 2014 9:52 AM

All replies

  • I'm pretty sure you need to register "Value" as a DependancyProperty.


    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Monday, January 27, 2014 3:18 PM
    Moderator
  • Value is a DependencyProperty of RangeBase. Do I have to re-register DPs of ancestor classes? If I were to register it, to what would I assign the return value of DependencyProperty::Register()? When implementing DPs from scratch, I would use SomeClass::_ValueProperty, but RangeBase::_ValueProperty is (presumably) private, and undocumented. Additionally, if I were to register it on my own, wouldn't it lose the benefits of being a RangeBase, and for example, not constrain between 'Maximum' and 'Minimum'?

    Also, why do I have to register 'Value', but not "Background", "BorderBrush" and  "BorderThickness"?

    Tuesday, January 28, 2014 5:14 AM
  • Also, in my original project, I have callbacks bound to OnValueChanged, which work, but the angle and the binding don't.
    Sunday, February 02, 2014 3:47 AM
  • Try switching out the TemplateBinding to instead use the following syntax:
    <RotateTransform Angle="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
    • Marked as answer by MagusOTB Monday, February 17, 2014 11:53 PM
    Monday, February 10, 2014 9:52 AM
  • That works, so I'll go ahead and mark this as answered, however, I'm still somewhat curious as to why the original way doesn't. The Documentation at: http://msdn.microsoft.com/en-us/library/ms742882(v=vs.110).aspx states:

    >>A TemplateBinding is an optimized form of a Binding for template scenarios, analogous to a Binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent}}

    I've tried both that way and yours (you have 'Mode=') and they both work, but the TemplateBinding doesn't seem to. If it's intended to behave the way it does, how do I differentiate from when I should be able to use a TemplateBinding and when I must use the long form?

    Also, I can't post links unless my account is 'verified,' and all the bing results for "verify msdn account" are either dead links or unanswered questions and there are no page text matches for 'verify' on any MSDN pages I can find. Wut?



    • Edited by MagusOTB Monday, February 17, 2014 11:53 PM spelling
    Saturday, February 15, 2014 8:50 PM
  • It looks like the restriction with TemplateBinding is that the type of the property that you are trying to bind should exactly match the type of the property you are assigning the value to. For instance if you TemplateBind value to the FontSize property on the TextBlock it works. I hope this helps.

    Thursday, March 13, 2014 6:40 PM