Reputation: 5627
I have a user control called InformationControl. I am using it in my window, like this:
<general:InformationControl Grid.Row="0" TimeToStart="{Binding TimeToStart}" Poor="{Binding Path=Mine.Poor}" Status="{Binding Path=Mine.MineStatus}"/>
The binding on the TimeToStart dependency property is working fine, but when I use Path=Object.Property
is doesn't seem to work.
However, when I use Path=Object.Property
on a regular control (i.e. not a UserControl) then it works fine:
<ItemsControl Grid.Row="2" Name="Items" ItemsSource="{Binding Path=Mine.Participants}">
I'm breaking in the getter for Mine, and in the binding logging it is saying that it is null, but it has definitely been set. Also the fact that it's trying to get the property in the first place makes me feel like the binding is correct but I can't work out why it's not working.
Do I need to do something different to make sure binding for nested properties works on UserControl dependency properties ?
Upvotes: 1
Views: 783
Reputation: 1346
Code behind for information control, set a break point at Debug.Print("newvalue...")
namespace WpfStackoverflow
{
/// <summary>
/// Interaction logic for InformationControl.xaml
/// </summary>
public partial class InformationControl : UserControl
{
public static readonly DependencyProperty TimeToStartProperty;
static InformationControl()
{
//FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata("");
TimeToStartProperty = DependencyProperty.Register("TimeToStart", typeof(string), typeof(InformationControl), new UIPropertyMetadata(string.Empty, UsernamePropertyChangedCallback));
}
public string TimeToStart
{
get {
return (string)GetValue(TimeToStartProperty);
}
set {
SetValue(TimeToStartProperty, value);
}
}
public InformationControl()
{
InitializeComponent();
string temp = TimeToStart;
}
private static void UsernamePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Debug.Print("OldValue: {0}", e.OldValue);
Debug.Print("NewValue: {0}", e.NewValue);
}
}
}
Main window xaml:
<Window x:Class="WpfStackoverflow.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfStackoverflow"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:InformationControl TimeToStart="{Binding Mine.Name}" />
</Grid>
</Window>
Main window code behind:
namespace WpfStackoverflow
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Parent p = new Parent();
p.Mine = new Mine();
p.Mine.Name = "Hello world";
this.DataContext = p;
}
}
}
Parent class:
namespace WpfStackoverflow
{
public class Parent:INotifyPropertyChanged
{
private Mine _mine;
public Mine Mine
{
get
{
return _mine;
}
set
{
_mine = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class Mine : INotifyPropertyChanged
{
private string _name;
public string Name { get { return _name; }
set
{
_name = value;
NotifyPropertyChanged();
}
}
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
I really have no idea what you are trying to accomplish, but if you look at my example, getting Mine.Name works in the user control if you set a break point in InformationControl's dependency property change callback. also note that the setter is never called because clr bypass setter and call setvalue directly.
Upvotes: 1