问题
I have been reading on Dependency properties for a few days and understand how they retrieve the value rather than to set/get them as in CLR properties. Feel free to correct me if I am wrong.
From my understanding all WPF controls like a TextBlock, Button etc that derive from DependencyObject would also contain dependency properties to store their values, instead of using CLR properties. This has the advantage of overriding local values in case animations are used, or inherit values if no local value is set at all etc.
I am now trying to come up with some samples to create and use my own dp.
1) Is it possible to create my own dependency property on an existing WPF control? Let say I would like a dependency property of type integer on WPF Textblock class ? Or do i have to create a new class derived from TextBlockBase in order to create my dependency property above in there?
2) In either case, let say I have created a dependency property on a WPF textblock class. Now I would like to utilize it by binding the content of label to that dependency property of the TextBlock. So that the label would always show the actual value of TextBlock's dp, no matter if its inherited or set locally.
Hopefully someone can help me with these two examples... Many Thanks, Kave
回答1:
You can use attached properties for it.
Define your property MyInt:
namespace WpfApplication5
{
public class MyProperties
{
public static readonly System.Windows.DependencyProperty MyIntProperty;
static MyProperties()
{
MyIntProperty = System.Windows.DependencyProperty.RegisterAttached(
"MyInt", typeof(int), typeof(MyProperties));
}
public static void SetMyInt(System.Windows.UIElement element, int value)
{
element.SetValue(MyIntProperty, value);
}
public static int GetMyInt(System.Windows.UIElement element)
{
return (int)element.GetValue(MyIntProperty);
}
}
}
Bind label content:
<Window x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication5"
Title="Window1" Height="300" Width="300">
<Grid>
<Label Margin="98,115,51,119" Content="{Binding Path=(local:MyProperties.MyInt), RelativeSource={x:Static RelativeSource.Self}}" local:MyProperties.MyInt="42"/>
</Grid>
</Window>
回答2:
You cant add DependencyProperties to existing type. While you can use AttachedProperty, logic behind using it and deriving new type is completly different.
In your case I would recomend to derive new type. Mainly because your logic is bound with this type. This is basic behind inheritance and is not bound with Dependency properties.
In case of AttachedProperty you are only giving another object awerness of values in different object. Something like Grid.Row is giving Grid awerness of its child and how it should position it. Object where this property is set is not aware of anything.
回答3:
Here is an example on an ovveride of the Run element:
using System;
using System.Windows;
using System.Windows.Documents;
namespace MyNameSpace.FlowDocumentBuilder
{
public class ModifiedRun : Run
{
static DateRun()
{
TextProperty.OverrideMetadata(typeof(DateRun),new FrameworkPropertyMetadata(string.Empty,FrameworkPropertyMetadataOptions.Inherits,null,CoerceValue));
}
private static object CoerceValue(DependencyObject d, object basevalue)
{
return "AAAAAAAA";
}
}
}
An the corresponding XAML is:
<FlowDocument xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
ColumnWidth="400"
FontSize="14"
FontFamily="Arial"
xmlns:local="clr-namespace:MyNameSpace.FlowDocumentBuilder;assembly=MyNameSpace.FlowDocumentBuilder"
>
<Paragraph><local:ModifiedRun Text="BBBBBBBBBB"/></Paragraph>
</FlowDocument>
来源:https://stackoverflow.com/questions/3940597/how-to-create-a-dependency-property-on-an-existing-control