2010-06-28 8 views
0

Je ne sais pas trop comment s'y prendre exactement. J'ai un ObservableCollection statique dans la classe NameField.cs. Je n'ai juste aucune idée de comment lier à la liste.WPF Custom Control - Comment lier une liste à partir d'un ObservableCollection statique?

  • Est-ce que je ne devrais pas utiliser un ListBox?
  • Devrais-je utiliser un DependencyProperty?
  • Devrais-je exposer ObservableCollection à travers une propriété ou par le public?

Je ne sais pas quoi faire ...

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace MyWPF 
{ 

    [TemplatePart(Name = NameField.ElementPrefixBox, Type = typeof(ListBox))] 
    public class NameField : Control 
    { 
     private const String ElementPrefixBox  = "PART_PrefixBox"; 

     private static ObservableCollection<NamePrefix> _namePrefixes; 

     static NameField() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(NameField), new FrameworkPropertyMetadata(typeof(NameField))); 

      _namePrefixes = new ObservableCollection<NamePrefix>(); 
     } 

     public static void AddNamePrefix(NamePrefix namePrefix) 
     { 
      lock (_namePrefixes) 
      { 
       _namePrefixes.Add(namePrefix); 
      } 
     } 

     public static IEnumerator<NamePrefix> GetNamePrefixes() 
     { 
      return _namePrefixes.GetEnumerator(); 
     } 

    } 

    /// <summary> 
    /// A Key/Value structure containing a Name Prefix ID and String value. 
    /// </summary> 
    public struct NamePrefix 
    { 
     public NamePrefix(Int32 id, String prefix) 
      : this() 
     { 
      ID = id; 
      Prefix = prefix; 
     } 

     public Int32 ID { get; set; } 
     public String Prefix { get; set; } 
    } 

} 

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:MyWPF" 
    xmlns:con="clr-namespace:MyWPF.Converters" 
    > 

    <Style TargetType="{x:Type local:NameField}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:NameField}"> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock TextWrapping="NoWrap" Text="Name:" VerticalAlignment="Center" Margin="3" /> 
         <ListBox x:Name="PART_PrefixBox" VerticalAlignment="Center" Margin="3" > 
          <ListBox.ItemBindingGroup> 
           <BindingGroup Name="NamePrefixes"/> 
          </ListBox.ItemBindingGroup> 
         </ListBox> 
        </StackPanel> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 

Répondre

3

Maintenant, je ne sais pas ce que vous faites en tant que votre classe étend le contrôle, donc je suppose que vous » re créer un contrôle personnalisé, donc ma réponse est basée sur cela. Je suppose également que NamePrefixes ne change jamais, c'est pourquoi vous utilisez une statique pour cela.

Je sauter les et fais statics:

public class NameField : Control 
{ 
    private const String ElementPrefixBox  = "PART_PrefixBox"; 

    public ObservableCollection<NamePrefix> NamePrefixes {get;private set;} 
    public NameField() 
    { 
     NamePrefixes = new ObservableCollection<NamePrefix>(); 
    } 
} 

<Style TargetType="{x:Type local:NameField}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:NameField}"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock TextWrapping="NoWrap" Text="Name:" VerticalAlignment="Center" Margin="3" /> 
        <ListBox x:Name="PART_PrefixBox" 
         VerticalAlignment="Center" 
         Margin="3" 
         ItemsSource="{Binding NamesPrefix, RelativeSource={RelativeSource FindAncestor, Ancestortype=Whatever}}" /> 
       </StackPanel> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Vous lient le ItemsSource à la racine du contrôle personnalisé (ne peut pas dire à partir du code ce qu'il est). Vous pourriez être en mesure d'appliquer un nom à votre racine, puis utilisez simplement ElementName=, IIRC cela fonctionne parfois.

Si vous devez ABSOLUMENT le rendre statique car TOUS les contrôles doivent être mis à jour quand l'un d'entre eux est mis à jour, vous pouvez rendre la collection observable statique et lier ItemsSource à {x: Static local: NameField.NamesPrefix}. Réalisez que vous ne pouvez lier que des propriétés publiques, pas des champs ou des méthodes (sans utiliser une source de données d'objet ou quelque chose).

Questions connexes