I am currently working on a MVVM project that uses a Window (with my ViewModel) and my own UserControl. The UserControl is nearly empty in the .xaml file because all of its functionality comes from code-behind, which draws different shapes. I wanted to bind a property from ViewModel to a DependencyProperty in the UserControl, but no matter what I do, i cannot get it to work. I have read tons of answers here and on different websites and noticed that it might be something with the UserControl's DataContext, but I eventually failed to fix the problem anyway. The way I raise the PropertyChanged event in my ViewModel is correct. I can successfully bind my property to other controls (like TextBoxes etc.), but not to my one. I would be grateful if you could explain to me why it is not working and how to fix that. Regards!
MainWindow.xaml binding:
<Grid Margin="10">
<local:FretboardControl Grid.Row="0" Fretboard="{Binding CurrentFretboard, Mode=TwoWay}"/>
</Grid>
FretboardControl.xaml:
<UserControl ...>
<Grid>
<TextBlock Text="{Binding Path=Fretboard, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:FretboardControl}}"/>
//the TextBlock above is just a test
<Canvas.../>
</Grid>
</UserControl>
FretboardControl.xaml.cs (code-behind):
public static readonly DependencyProperty FretboardProperty = DependencyProperty.Register
(nameof(Fretboard), typeof(Fretboard), typeof(FretboardControl), new PropertyMetadata(new Fretboard(), PropertyChangedCallback));
public Fretboard Fretboard {
get {
return GetValue(FretboardProperty) as Fretboard;
}
set {
SetValue(FretboardProperty, value);
}
}
protected static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e) {
//breakpoint here. It is reached only once during runtime:
//at start, when the default value is inserted
if (o is FretboardControl) {
(o as FretboardControl).RefreshFretboard();
}
}
DataContext = this;in the UserControl's constructor? That said,AncestorType=UserControlshould be ok (instead oflocal:FretboardControl). - Clemensif (o is FretboardControl)followed by(o as FretboardControl)is pointless. Just call((FretboardControl)o).RefreshFretboard(). And if the PropertyChangedCallback is called that is usually in indication that the property was set to a value other than the default value. So your Binding may have worked... - Clemens