Attached Properties [modified]
-
I have a custom control with attached properties. If I set these properties in the XAML they're fine. If I set them from the CS code, they appear to get set, but the rendered form doesn't change. I tried calling ApplyTemplate() and UpdateLayout, but nothing causes the rendered control to change from appearance seen in the XAML. What am I missing? EDIT ============== Here's my property code:
public class RadGridTitleBar
{
//--------------------------------------------------------------------------------
public static readonly DependencyProperty TextContentProperty =
DependencyProperty.RegisterAttached("TextContent",
typeof(object),
typeof(RadGridTitleBar));//-------------------------------------------------------------------------------- public object TextContent { get { return (object)base.GetValue(RadGridTitleBar.TextContentProperty); } set { base.SetValue(RadGridTitleBar.TextContentProperty, value); } }
}
EDIT AGAIN ========================= Should I even be using attached properties?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001modified on Monday, July 20, 2009 11:42 AM
-
I have a custom control with attached properties. If I set these properties in the XAML they're fine. If I set them from the CS code, they appear to get set, but the rendered form doesn't change. I tried calling ApplyTemplate() and UpdateLayout, but nothing causes the rendered control to change from appearance seen in the XAML. What am I missing? EDIT ============== Here's my property code:
public class RadGridTitleBar
{
//--------------------------------------------------------------------------------
public static readonly DependencyProperty TextContentProperty =
DependencyProperty.RegisterAttached("TextContent",
typeof(object),
typeof(RadGridTitleBar));//-------------------------------------------------------------------------------- public object TextContent { get { return (object)base.GetValue(RadGridTitleBar.TextContentProperty); } set { base.SetValue(RadGridTitleBar.TextContentProperty, value); } }
}
EDIT AGAIN ========================= Should I even be using attached properties?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001modified on Monday, July 20, 2009 11:42 AM
For an Attached Property (as opposed to a regular Dependency Property), you will want to implement the Accessors as methods, not a property.
public static void SetTextContent(UIElement element, Object value)
{
element.SetValue(TextContentProperty, value);
}
public static Object GetTextContent(UIElement element)
{
return (Object)element.GetValue(TextContentProperty);
}As to whether or not you should be using an Attached Property, this link should help you answer that question: http://msdn.microsoft.com/en-us/library/ms749011.aspx[^] Hope this helps, Keith EDIT: You may also want to look at Setting Appropriate Metadata Flags section at http://msdn.microsoft.com/en-us/library/ms753358.aspx[^] in regard to how the control should handle updates to this property.
modified on Monday, July 20, 2009 12:19 PM
-
For an Attached Property (as opposed to a regular Dependency Property), you will want to implement the Accessors as methods, not a property.
public static void SetTextContent(UIElement element, Object value)
{
element.SetValue(TextContentProperty, value);
}
public static Object GetTextContent(UIElement element)
{
return (Object)element.GetValue(TextContentProperty);
}As to whether or not you should be using an Attached Property, this link should help you answer that question: http://msdn.microsoft.com/en-us/library/ms749011.aspx[^] Hope this helps, Keith EDIT: You may also want to look at Setting Appropriate Metadata Flags section at http://msdn.microsoft.com/en-us/library/ms753358.aspx[^] in regard to how the control should handle updates to this property.
modified on Monday, July 20, 2009 12:19 PM
My XAML looks like this:
<Style x:Key="RadGridTitleBarStyle" TargetType="{x:Type udpcontrols:RadGridTitleBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type udpcontrols:RadGridTitleBar}">
<Border x:Name="PART_Border"
Background="White"
BorderBrush="Black"
BorderThickness="1,1,1,1">
<Grid>
<Label x:Name="PART_Label"
Content="{Binding Source=RadGridTitleBar, Path=TextContent}"/>Isn't this correct?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
My XAML looks like this:
<Style x:Key="RadGridTitleBarStyle" TargetType="{x:Type udpcontrols:RadGridTitleBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type udpcontrols:RadGridTitleBar}">
<Border x:Name="PART_Border"
Background="White"
BorderBrush="Black"
BorderThickness="1,1,1,1">
<Grid>
<Label x:Name="PART_Label"
Content="{Binding Source=RadGridTitleBar, Path=TextContent}"/>Isn't this correct?
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001I think you want TemplateBinding instead.
<Label x:Name="PART_Label" Content="{TemplateBinding TextContent}" />
I'm with Keith on this one. I'd suggest a regular DependencyProperty instead of an attached one since its something that every instance of the your custom control has (like the Label.Content property) and is not something you would attach to another control (like how Grid.Row attaches to other controls).
-
I think you want TemplateBinding instead.
<Label x:Name="PART_Label" Content="{TemplateBinding TextContent}" />
I'm with Keith on this one. I'd suggest a regular DependencyProperty instead of an attached one since its something that every instance of the your custom control has (like the Label.Content property) and is not something you would attach to another control (like how Grid.Row attaches to other controls).
I tried that and it's still not working. So that it's all in one place, I now have the following: The XAML looks like this:
<Style x:Key="RadGridTitleBarStyle" TargetType="{x:Type controls:RadGridTitleBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:RadGridTitleBar}">
<Border x:Name="PART_Border" >
<Grid>
<Label x:Name="PART_Label" Content="{TemplateBinding TextContent}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>And the class looks like this:
public class RadGridTitleBar : Control
{
static RadGridTitleBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RadGridTitleBar),
new FrameworkPropertyMetadata(typeof(RadGridTitleBar)));
}public static readonly DependencyProperty TextContentProperty = DependencyProperty.Register("TextContent", typeof(object), typeof(RadGridTitleBar)); public object TextContent { get { return (object)base.GetValue(TextContentProperty); } set { base.SetValue(TextContentProperty, value); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); Label label = base.GetTemplateChild("PART\_Label") as Label; if (label != null) { label.Content = (object)this.TextContent; } }
}
Like you, I saw no need for attached properties, but that's what everyone seems to talk about.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
I think you want TemplateBinding instead.
<Label x:Name="PART_Label" Content="{TemplateBinding TextContent}" />
I'm with Keith on this one. I'd suggest a regular DependencyProperty instead of an attached one since its something that every instance of the your custom control has (like the Label.Content property) and is not something you would attach to another control (like how Grid.Row attaches to other controls).
Well, I started from scratch, and came up with something that a) appears to work, and b) contains a LOT less code. I'll post a new thread if I continue to have issues. To say that you've opened my eyes a bit would be an understatement.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001 -
I tried that and it's still not working. So that it's all in one place, I now have the following: The XAML looks like this:
<Style x:Key="RadGridTitleBarStyle" TargetType="{x:Type controls:RadGridTitleBar}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:RadGridTitleBar}">
<Border x:Name="PART_Border" >
<Grid>
<Label x:Name="PART_Label" Content="{TemplateBinding TextContent}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>And the class looks like this:
public class RadGridTitleBar : Control
{
static RadGridTitleBar()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RadGridTitleBar),
new FrameworkPropertyMetadata(typeof(RadGridTitleBar)));
}public static readonly DependencyProperty TextContentProperty = DependencyProperty.Register("TextContent", typeof(object), typeof(RadGridTitleBar)); public object TextContent { get { return (object)base.GetValue(TextContentProperty); } set { base.SetValue(TextContentProperty, value); } } public override void OnApplyTemplate() { base.OnApplyTemplate(); Label label = base.GetTemplateChild("PART\_Label") as Label; if (label != null) { label.Content = (object)this.TextContent; } }
}
Like you, I saw no need for attached properties, but that's what everyone seems to talk about.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001John Simmons / outlaw programmer wrote:
Label label = base.GetTemplateChild("PART_Label") as Label;
if (label != null)
{
label.Content = (object)this.TextContent;
}This will only assign the content once (and maybe before the TextContent is set on your control). If you intended it to be a binding, you would need to actually set the binding in code (something like
label.SetBinding(Label.ContentProperty,...)
I believe) Also, I don't know what the standard opinion is on using "PART_*", but for what it's worth, I generally only use them if I need to do something that I cannot do from XAML with bindings. One case was when I needed to have "segments" for an LED control and had to turn them on and off from code. -
John Simmons / outlaw programmer wrote:
Label label = base.GetTemplateChild("PART_Label") as Label;
if (label != null)
{
label.Content = (object)this.TextContent;
}This will only assign the content once (and maybe before the TextContent is set on your control). If you intended it to be a binding, you would need to actually set the binding in code (something like
label.SetBinding(Label.ContentProperty,...)
I believe) Also, I don't know what the standard opinion is on using "PART_*", but for what it's worth, I generally only use them if I need to do something that I cannot do from XAML with bindings. One case was when I needed to have "segments" for an LED control and had to turn them on and off from code.I started over, and don't even have an
OnApplyTemplate
method anymore. :)"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001