-
- kemarofangs
- Posts: 32
- Joined:
How To Implement Attached Property?
Another question, let's say I've made a control and want to customize sub-components of that control using xaml. Would I use attached properties to do this? Below I'm trying to assign a border's corner radius in this way. Where have I gone wrong and what needs to change for this to work?
Assigning the dependency property to readonly doesn't seem to be allowed (compile time error).
I could do this differently if everything wasn't required to be a usercontrol.
Maybe change thisto something like this Just a thought though. Admittedly, I don't know how difficult it is to pair xaml with a code behind in noesis.
Assigning the dependency property to readonly doesn't seem to be allowed (compile time error).
I could do this differently if everything wasn't required to be a usercontrol.
Maybe change this
Code: Select all
[Noesis.UserControlSource("Assets/Darren/Code/QuickSwap.xaml")]
Code: Select all
[Noesis.Source(Noesis.Border,"Assets/Darren/Code/QuickSwap.xaml")]
Code: Select all
<darren:QuickSwap x:Name="m_quickSwap_leftHand" Canvas.Top="75" Canvas.Left="0" Height="150" Width="100" CornerRadius="25" />
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:noesis="clr-namespace:NoesisGUIExtensions"
x:Class="Darren.QuickSwap" Opacity=".5">
<Border x:Name="m_border" Background="#FF595959" BorderBrush="Black" BorderThickness="5" />
</UserControl>
Code: Select all
namespace Darren
{
[Noesis.UserControlSource("Assets/Darren/Code/QuickSwap.xaml")]
public class QuickSwap : Noesis.UserControl
{
#region Variables & Properties
private Noesis.Border m_border = null;
#region Attached Properties
/// <summary>
/// EX) http://www.codemag.com/article/1405061
/// </summary>
public Noesis.CornerRadius CornerRadius
{
get
{
// Retrieve Value
return (Noesis.CornerRadius)GetValue(CornerRadiusProperty);
}
set
{
// Mirror value to subcomponent
if (null == m_border)
{
m_border = FindName("m_border") as Noesis.Border;
}
if (null != m_border)
{
m_border.CornerRadius = value;
}
// Assign Value
SetValue(CornerRadiusProperty, value);
}
}
/// <summary>
///
/// </summary>
public static Noesis.DependencyProperty
CornerRadiusProperty =
Noesis.DependencyProperty.Register(
"CornerRadius",
typeof(Noesis.CornerRadius), typeof(QuickSwap),
new Noesis.PropertyMetadata(""));
#endregion Attached Properties
#endregion Variables & Properties
/// <summary>
/// Initialization.
/// </summary>
public void OnPostInit()
{
}
}
}
-
-
sfernandez
Site Admin
- Posts: 2062
- Joined:
Re: How To Implement Attached Property?
Hi,
Attached properties are used to add custom behaviors to other classes. For example, the Panel.ZIndex that you can set on any Panel child, is only useful and only has sense in the Panel logic. Child elements don't know what to do with that value.
If you define a new dependency property in your QuickSwap user control, and you set the property in the same control, this could be considered as a normal dependency property, not an attached one.
The readonly keyword can't be used on the DependencyProperty definition because some limitations with mono and how we initialize our plugin.
About the UserControlSource attribute, it is required to pair the XAML file with the UserControl code. You cannot set that attribute to any other type of control.
Your example should look like this if defining an Attached Property:
And if it is going to be used as a normal property, something like this:
Attached properties are used to add custom behaviors to other classes. For example, the Panel.ZIndex that you can set on any Panel child, is only useful and only has sense in the Panel logic. Child elements don't know what to do with that value.
If you define a new dependency property in your QuickSwap user control, and you set the property in the same control, this could be considered as a normal dependency property, not an attached one.
The readonly keyword can't be used on the DependencyProperty definition because some limitations with mono and how we initialize our plugin.
About the UserControlSource attribute, it is required to pair the XAML file with the UserControl code. You cannot set that attribute to any other type of control.
Your example should look like this if defining an Attached Property:
Code: Select all
[UserControlSource("Assets/Darren/Code/QuickSwap.xaml")]
public class QuickSwap: UserControl
{
public static DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached(
"CornerRadius", typeof(CornerRadius), typeof(QuickSwap),
new PropertyMetadata(new CornerRadius(), OnCornerRadiusChanged));
private static void OnCornerRadiusChanged(object sender, DependencyPropertyChangedEventArgs e)
{
//CornerRadius cornerRadius = (CornerRadius)e.NewValue;
// do something with the new corner radius and the sender element
}
public static CornerRadius GetCornerRadius(DependencyObject element)
{
return (CornerRadius)element.GetValue(CornerRadiusProperty);
}
public static void SetCornerRadius(DependencyObject element, CornerRadius cornerRadius)
{
element.SetValue(CornerRadiusProperty, cornerRadius);
}
}
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:darren="clr-namespace:Darren"
x:Class="Darren.QuickSwap">
<Rectangle darren:QuickSwap.CornerRadius="4,2,4,2"/>
</UserControl>
Code: Select all
[UserControlSource("Assets/Darren/Code/QuickSwap.xaml")]
public class QuickSwap: UserControl
{
public static DependencyProperty CornerRadiusProperty = DependencyProperty.Register(
"CornerRadius", typeof(CornerRadius), typeof(QuickSwap),
new PropertyMetadata(new CornerRadius()));
public CornerRadius CornerRadius
{
get
{
return (CornerRadius)GetValue(CornerRadiusProperty);
}
set
{
SetValue(CornerRadiusProperty, cornerRadius);
}
}
}
Code: Select all
<darren:QuickSwap CornerRadius="10,10,20,20" />
Re: How To Implement Attached Property?
This will be solved in v1.3The readonly keyword can't be used on the DependencyProperty definition because some limitations with mono and how we initialize our plugin.
This attribute will also disappear in v1.3 and you will load the XAML manually. Normally this code will be automatically generated (similar to the automatic hidden code generated by Visual Studio in WPF).About the UserControlSource attribute, it is required to pair the XAML file with the UserControl code. You cannot set that attribute to any other type of control.
More details, soon. : )
-
- kemarofangs
- Posts: 32
- Joined:
Re: How To Implement Attached Property?
v1.3 sounds quite promising. Thanks for both examples regarding attached and normal properties. Definitely going to make use of both of them. There's nothing special I need to do in order to guard against memory leaks using these basic patterns correct?
Here's my working code thanks to your examples / explanations.
Here's my working code thanks to your examples / explanations.
Code: Select all
namespace Darren
{
[Noesis.UserControlSource("Assets/Darren/Code/QuickSwap.xaml")]
public class QuickSwap : Noesis.UserControl
{
#region Variables & Properties
#region Dependency Properties
/// <summary>
/// EX) http://www.codemag.com/article/1405061
/// </summary>
public static Noesis.DependencyProperty CornerRadiusProperty = Noesis.DependencyProperty.Register(
"CornerRadius",
typeof(Noesis.CornerRadius),
typeof(QuickSwap),
new Noesis.PropertyMetadata(new Noesis.CornerRadius(), OnCornerRadiusChanged));
/// <summary>
///
/// </summary>
public Noesis.CornerRadius CornerRadius
{
get
{
return (Noesis.CornerRadius)GetValue(CornerRadiusProperty);
}
set
{
SetValue(CornerRadiusProperty, value);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void OnCornerRadiusChanged(object sender, Noesis.DependencyPropertyChangedEventArgs e)
{
Darren.QuickSwap quickSwap = sender as Darren.QuickSwap;
if (null != quickSwap)
{
Noesis.Border border = quickSwap.FindName("m_border") as Noesis.Border;
if (null != border)
{
Noesis.CornerRadius cornerRadius = (Noesis.CornerRadius)e.NewValue;
if (null != cornerRadius)
{
border.CornerRadius = cornerRadius;
}
}
}
}
#endregion Dependency Properties
#endregion Variables & Properties
/// <summary>
/// Initialization.
/// </summary>
public void OnPostInit()
{
}
}
}
-
-
sfernandez
Site Admin
- Posts: 2062
- Joined:
Re: How To Implement Attached Property?
You are welcome.
Your code seems correct and you don't have to worry about memory leaks there, you are just doing normal casts of already created objects.
Your code seems correct and you don't have to worry about memory leaks there, you are just doing normal casts of already created objects.
Who is online
Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests