2010-10-15 4 views
7

J'ai lu sur les propriétés de dépendance pendant quelques jours et je comprends comment ils récupèrent la valeur plutôt que de les définir/les obtenir comme dans les propriétés CLR. N'hésitez pas à me corriger si je me trompe. D'après ce que j'ai compris, tous les contrôles WPF comme un TextBlock, Button etc qui dérivent de DependencyObject contiendraient également des propriétés de dépendance pour stocker leurs valeurs, au lieu d'utiliser les propriétés CLR. Cela a l'avantage de surcharger les valeurs locales en cas d'utilisation d'animations, ou d'hériter des valeurs si aucune valeur locale n'est définie, etc.Comment créer une propriété Dependency sur un contrôle existant?

J'essaie maintenant de trouver des exemples pour créer et utiliser mon propre dp.

1) Est-il possible de créer ma propre propriété de dépendance sur un contrôle WPF existant? Disons que je voudrais une propriété de dépendance de type entier sur la classe WPF Textblock? Ou dois-je créer une nouvelle classe dérivée de TextBlockBase afin de créer ma propriété de dépendance ci-dessus?

2) Dans les deux cas, disons que j'ai créé une propriété de dépendance sur une classe WPF textblock. Maintenant, je voudrais l'utiliser en liant le contenu du label à cette propriété de dépendance du TextBlock. Alors que l'étiquette montrerait toujours la valeur réelle du dp de TextBlock, peu importe si elle est héritée ou définie localement.

Espérons que quelqu'un peut me aider avec ces deux exemples ... Merci beaucoup, Kave

Répondre

6

Vous pouvez utiliser attached properties pour elle.

Définir votre propriété 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 contenu de l'étiquette:


<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> 
+0

grâce, ce qui est également une bonne alternative, que je vais essayer bientôt . – Houman

1

Tu ne peux pas ajouter DependencyProperties type existant. Alors que vous pouvez utiliser AttachedProperty, la logique derrière l'utiliser et dériver un nouveau type est complètement différente.

Dans votre cas, je recommanderais de dériver un nouveau type. Principalement parce que votre logique est liée à ce type. Ceci est basique derrière l'héritage et n'est pas lié aux propriétés de dépendance.

Dans le cas d'AttachedProperty, vous ne donnez à un autre objet que des valeurs de différents objets. Quelque chose comme Grid.Row donne Grid awerness de son enfant et comment il devrait le positionner. L'objet où cette propriété est définie n'a pas connaissance de quoi que ce soit.

+0

merci. Pourquoi voudrais-je jamais créer dp? J'ai lu que certaines personnes créent leurs propres. Je voudrais voir un exemple où il est logique de créer votre propre dp ... – Houman

0

Voici un exemple sur un ovveride de l'élément Run:

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"; 
     } 
    } 
} 

Un XAML correspondant est:

<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> 
Questions connexes