Xaml Binding Not Working on Dependency Property

XAML binding not working on dependency property?

The dependency property declaration must look like this:

public static readonly DependencyProperty TestProperty =
DependencyProperty.Register(
nameof(Test),
typeof(string),
typeof(MyControl),
new PropertyMetadata("DEFAULT"));

public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}

The binding in the UserControl's XAML must set the control instance as the source object, e.g. by setting the Bindings's RelativeSource property:

<UserControl x:Class="WpfTest.MyControl" ...>
<TextBlock Text="{Binding Test,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>

Also very important, never set the DataContext of a UserControl in its constructor. I'm sure there is something like

DataContext = this;

Remove it, as it effectively prevents inheriting a DataContext from the UserConrol's parent.

By setting Source = DataContext in the Binding in code behind you are explicitly setting a binding source, while in

<local:MyControl Test="{Binding MyText}" />

the binding source implicitly is the current DataContext. However, that DataContext has been set by the assignment in the UserControl's constructor to the UserControl itself, and is not the inherited DataContext (i.e. the view model instance) from the window.

WPF dependency property binding not working

Do you set the DataContext of the SliderControl to itself somewhere?

Try to specify the source of the binding explicitly:

<cl:SliderControl x:Name="valvePosUC" Minimum="0" Maximum="100" Title="Valve Position" 
Value="{Binding DataContext.ValvePos_SliderValue, RelativeSource={RelativeSource AncestorType=Window}}" />

Why is my Dependency Property Binding is not working as expected?

The Binding must be TwoWay:

SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}"

You could declare the property such that it binds TwoWay by default:

public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register(
nameof(SelectedItem),
typeof(object),
typeof(DragAndDropListView),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
SelectedItemPropertyChangedCallback));

CustomControl DependencyProperty Binding not working correct

You need to set binding Mode to TwoWay, because by default binding works one way, i.e. loading changes from the view model, but not updating it back.

<controls:FileSelectorTextBox FileName="{Binding FileName, Mode=TwoWay}" Height="30" />

Another option is to declare your custom dependency property with BindsTwoWayByDefault flag, like this:

public static readonly DependencyProperty FileNameProperty =
DependencyProperty.Register("FileName",
typeof(string),
typeof(FileSelectorTextBox),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

Also when you change your custom dependency property from inside your control use SetCurrentValue method instead of directly assigning the value using property setter. Because if you assign it directly you will break the binding.

So, instead of:

FileName = dlg.FileName;

Do like this:

SetCurrentValue(FileNameProperty, dlg.FileName);

Binding not working when binding to dependency property of class (only working one way)

It's actually correctly changing the value in both ways, you would notice it with a Debug.Print. Only, the setter of your property is not necessarily called by the framework when performing Binding. The issue in your code is that you're performing InvalidateVisual() in the setter of the StartAngle property, but as MSDN states here:

In all but exceptional circumstances, your wrapper implementations
should perform only the GetValue and SetValue actions, respectively.
The reason for this is discussed in the topic XAML Loading and
Dependency Properties.

You should instead declare your DependencyProperty so that it automatically invalidates the visual upon update, using the FrameworkPropertyMetadata object:

public static readonly DependencyProperty StartAngleProperty = DependencyProperty.Register(
"StartAngle",
typeof(int),
typeof(Pie),
new FrameworkPropertyMetadata(default(int), FrameworkPropertyMetadataOptions.AffectsRender)
);

And leave your getter/setter like this:

public int StartAngle {
get { return (int)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}

Now you'll see your control redrawing when moving the slider.

WPF Binding to UserControl´s DependencyProperty not working as expected

You didn't share enough code for anybody to recreate the issue, but reading between the lines, I'm guessing that Label is in your UserControl XAML. If TestValue is a property of your UserControl, this will probably work:

<Label Content="{Binding TestValue, RelativeSource={RelativeSource AncestorType=UserControl}}" />

However, one reason you might have done that (and had it semi-work, with literal strings) is if you made your UserControl its own DataContext. In that case, then the problem is that you made your UserControl its own DataContext. If you did that, that Binding on the bound one is being evaluated in the context of the UserControl, which does not have a Settings.Setting123 property.

What a control's DataContext means, is that when you have a Binding on one of the controls properties or inside its XAML, that's where the Binding goes to look for the property you bind to. You're explicitly telling it to look in the wrong place.

If you make your UserControl its own DataContext, you can't bind anything to it. That's why you shouldn't do that. It's like one of those machines that does nothing but unplug itself from the wall. Instead, use {RelativeSource AncestorType=UserControl} bindings as above inside the UserControl XAML.

I shouldn't have to guess. You claim you created a minimal verifiable example, but didn't bother sharing it. If you share it, we can solve your problem with confidence.

Data Binding not working for User Control's custom Property with Dependency Property (Output window is clean)

As explained in XAML Loading and Dependency Properties, the CLR wrapper of a dependency property may not be called, so your breakpoints aren't hit and the ShowSlideContent method isn't executed. Instead, the framework directly calls the dependency property's GetValue and SetValue methods.

Because the current WPF implementation of the XAML processor behavior
for property setting bypasses the wrappers entirely, you should not
put any additional logic into the set definitions of the wrapper for
your custom dependency property. If you put such logic in the set
definition, then the logic will not be executed when the property is
set in XAML rather than in code.

In order to react on changed property values, you'll have to register a PropertyChangedCallback with property metadata:

public ISlide PresentationSlide
{
get { return (ISlide)GetValue(PresentationSlideProperty); }
set { SetValue(PresentationSlideProperty, value); }
}

public static readonly DependencyProperty PresentationSlideProperty =
DependencyProperty.Register(
nameof(PresentationSlide),
typeof(ISlide),
typeof(PresentationViewer),
new PropertyMetadata(null, PresentationSlidePropertyChanged));

private static void PresentationSlidePropertyChanged(
DependencyObject o, DependencyPropertyChangedEventArgs e)
{
((PresentationViewer)o).ShowSlideContent();
}

Or, with a lambda expression:

public static readonly DependencyProperty PresentationSlideProperty =
DependencyProperty.Register(
nameof(PresentationSlide),
typeof(ISlide),
typeof(PresentationViewer),
new PropertyMetadata(null,
(o, e) => ((PresentationViewer)o).ShowSlideContent()));


Related Topics



Leave a reply



Submit