You can create a user control along the lines of...
<UserControl x:Class="ChainBinding.CaptionGuy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid>
<Label Name="CaptionLabel"/>
</Grid>
</UserControl>
...and instrument it with your dependency property like this...
#region Caption (DependencyProperty)
public string Caption
{
get { return (string)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(CaptionGuy),
new PropertyMetadata{PropertyChangedCallback = CaptionChanged});
private static void CaptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CaptionGuy cg = d as CaptionGuy;
if (cg != null && e.NewValue!=null)
{
cg.CaptionLabel.Content = e.NewValue.ToString();
}
}
#endregion
Then you can deploy it in a WPF application like this...
<Grid>
<chainBinding:CaptionGuy Caption="{Binding VmCaption}"/>
</Grid>
And the corresponding View Model (or code-behind if that's your design) would look like this...
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
Dispatcher dispatcher = Dispatcher.CurrentDispatcher;
DispatcherTimer dt = new DispatcherTimer(new TimeSpan(0,0,0,5), DispatcherPriority.Normal,
delegate
{
VmCaption = DateTime.Now.ToString("G");
}, dispatcher);
dt.Start();
}
private string _vmCaption;
public string VmCaption
{
[DebuggerStepThrough]
get { return _vmCaption; }
[DebuggerStepThrough]
set
{
if (value != _vmCaption)
{
_vmCaption = value;
OnPropertyChanged("VmCaption");
}
}
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
This example just updates the caption with the time every 5 seconds.
Of course this answer uses a callback on the dependency property, but this is a matter where circumstantial practicality wins out over declarative programming.