katit
katit

Reputation: 17905

Make dependency property bind two way in custom control

I have custom control with following:

<TextBox Grid.Column="3" Text="{TemplateBinding SampleValue}" />

public static readonly DependencyProperty SampleValueProperty =
            DependencyProperty.RegisterAttached("SampleValue", typeof(string), typeof(IdattFilterBox), new PropertyMetadata(null));

public string SampleValue
        {
            get { return GetValue(SampleValueProperty) as string; }
            set { this.SetValue(SampleValueProperty, value); }
        }

In a UserControl where I declare my custom control I have XAML like this:

<my:SampleBox SampleValue="{Binding SampleValue, Mode=TwoWay}" />

and ViewModel like so:

public string SampleValue
        {
            get
            {
                return this.sampleValue;
            }

            set
            {
                this.sampleValue = value;
            }
        }

I don't care about INotifyPropertyChanged on VM (so don't tell me about it :) ) Right now it's working as far as displaying text in text box just like I set it in VM. But when I modify this text - it doesn't get bubbled up back into VM.

What should I do? I guess I have to write some code inside custom control? Should I deal with TextBox PART and catch LostFocus? Or how does it work with TemplateBinding?

Upvotes: 5

Views: 2759

Answers (4)

Mike Post
Mike Post

Reputation: 6460

TemplateBinding is inherently one way. You need to use a Binding with Mode=TwoWay and

Source={Binding RelativeSource={RelativeSource TemplatedParent}}.

Upvotes: 4

Anatolii Gabuza
Anatolii Gabuza

Reputation: 6260

First that occurred to add Source binding that will show that you're binding element from context of source element.
Try to use something like:

<my:SampleBox SampleValue="{Binding SampleValue, Source={StaticResource someViewModel}, Mode=TwoWay}" />

Upvotes: 0

Justin XL
Justin XL

Reputation: 39006

TemplateBinding is only OneWay.

If you are using Silverlight 4, you can try this,

{Binding SampleValue, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}

Upvotes: 7

Valentin Kuzub
Valentin Kuzub

Reputation: 12073

Maybe you want DependencyProperty.Register instead of DependencyProperty.RegisterAttached ?

Given your title you probably don't want to create attached property.

edit:

its unclear to me from code samples you provide what exactly are you trying to do.

To get two way binding you probably got 2 directions here

  • Add INotifyPropertyChanged (which you don't want for some reason)

  • deal with new PropertyMetadata(null) Instead of null supply a handler for change event there (along with default value if needed) and do desired things with NewValue there.

If possible update question so its easier to understand which control has what and who binds how. (more XAML should do)

Also notice that TextBox doesn't fire events unless it loses focus.

Upvotes: 2

Related Questions