So I tried using DependencyProperty
to solve my issues with regards to passing the local ViewModel across child Views. However a question popped in my head.
For example I need to make multiple instances of a certain FrameworkElement
, say, a UserControl
. That UserControl
has a DependencyProperty
defined. As stated in books, a dependency property instance should be static
and readonly
. How would the DependencyProperty
work in that kind of scenario? Would it work the same way as a conventional UserControl
property, or whatever object instance you pass to the DependencyProperty
, it'll be passed across all instances of the said UserControl
?
Yes, it will operate as a normal property. If you need a property for a specific control, that is one property for a single control, you can use just dependency property. They will be passed through all the instances of the class. But if you want the property on many controls, then should use the attached dependency property, which will be available to all members within a certain namespace. Properties, such as: Canvas.Top, DockPanel.Dock are attached DependencyProperty.
Sample of attached dependency properties:
public class MyDependencyClass : DependencyObject
{
public static readonly DependencyProperty IsSelectedProperty;
public static void SetIsSelected(DependencyObject DepObject, Boolean value)
{
DepObject.SetValue(IsSelectedProperty, value);
}
public static Boolean GetIsSelected(DependencyObject DepObject)
{
return (Boolean)DepObject.GetValue(IsSelectedProperty);
}
private static bool IsSelectedValid(object Value)
{
if (Value.GetType() == typeof(bool))
{
return true;
}
else
{
return false;
}
}
static MyDependencyClass()
{
FrameworkPropertyMetadata MetaData = new FrameworkPropertyMetadata((Boolean)false);
IsSelectedProperty = DependencyProperty.RegisterAttached("IsSelected",
typeof(Boolean),
typeof(MyDependencyClass),
MetaData,
new ValidateValueCallback(IsSelectedValid));
}
}
They also contain useful callback's like OnPropertyChangedCallback, ValidateValueCallback which can be placed in an additional logic.
These properties are also available in XAML. Add "local" namespace:
xmlns:local="clr-namespace:SampleApp"
Define for element's:
<Button Name="Button1" local:MyDependencyClass.IsSelected="True" />
<Button Name="Button2" local:MyDependencyClass.IsSelected="False" />
...
<ListBoxItem Name="Sample" local:MyDependencyClass.IsSelected="True" />
Access to property in triggers:
<Trigger Property="local:MyDependencyClass.IsSelected" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
Work with attached dependency properties in code:
if (CurrentButtonName == MyButton.Name)
{
MyDependencyClass.SetIsSelected(CurrentButton, true);
}
else
{
MyDependencyClass.SetIsSelected(CurrentButton, false);
}
For more info see: http://msdn.microsoft.com/en-us/library/ms749011.aspx