2010-12-15 89 views
0

J'ai un contrôle personnalisé auquel j'applique le modèle. Dans le contrôle personnalisé interne, j'ai défini les propriétés qui sont liées au contrôle basé sur un modèle dans le style. Si je suis abonné à l'événement Loaded et que j'essaie d'obtenir les propriétés, elles sont nulles. Si toutefois je surpasse le OnPropertyChanged, ils ont des valeurs. Quelqu'un peut-il expliquer pourquoi est-ce le cas? Veuillez regarder la propriété ColumnEntity.Impossible d'obtenir la valeur de la propriété lors de l'utilisation des styles

Merci.

J'ai enlevé quelques pièces pour briefety

<!-- This code is based on http://www.codeproject.com/KB/WPF/DataGridFilterLibrary.aspx --> 

    <Style TargetType="{x:Type local:DataGridColumnFilter}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:DataGridColumnFilter}"> 
       <Border Background ="{TemplateBinding Background}" 
         BorderBrush="{TemplateBinding BorderBrush}" 
         BorderThickness="{TemplateBinding BorderThickness}"> 
        <TextBox VerticalAlignment="Top" VerticalContentAlignment="Center" Background="AliceBlue" 
         Text="{Binding 
          RelativeSource={RelativeSource AncestorType={x:Type local:DataGridColumnFilter}}, 
          Path=QueryEntity.Text, Mode=OneWayToSource, UpdateSourceTrigger=Explicit}"> 
        </TextBox> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<Style x:Key="{ComponentResourceKey 
    TypeInTargetAssembly={x:Type local:DataGridColumnFilter}, ResourceId=DataGridHeaderFilterControlStyle}" 
    TargetType="{x:Type DataGridColumnHeader}"> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type DataGridColumnHeader}"> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition /> 
         <RowDefinition /> 
        </Grid.RowDefinitions> 

        <local:DataGridColumnFilter Grid.Row="0" 
         DataGridEntity="{Binding 
          RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=.}" 
         ColumnEntity="{Binding 
          RelativeSource={RelativeSource AncestorType={x:Type DataGridColumnHeader}}, Path=Column}" 
         ItemsSourceEntity ="{Binding 
          RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, 
          Path=ItemsSource}"/> 

        <theme:DataGridHeaderBorder Grid.Row="1" 
          SortDirection ="{TemplateBinding SortDirection}" 
          IsHovered  ="{TemplateBinding IsMouseOver}" 
          IsPressed  ="{TemplateBinding IsPressed}" 
          IsClickable ="{TemplateBinding CanUserSort}" 
          Background  ="{TemplateBinding Background}" 
          BorderBrush ="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          Padding  ="{TemplateBinding Padding}" 
          SeparatorBrush ="{TemplateBinding SeparatorBrush}" 
          SeparatorVisibility="{TemplateBinding SeparatorVisibility}"> 

         <TextBlock Grid.Row="1" TextWrapping="Wrap" 
          Text    ="{TemplateBinding Content}" 
          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
          VerticalAlignment ="{TemplateBinding VerticalContentAlignment}" 
          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"> 
         </TextBlock> 
        </theme:DataGridHeaderBorder> 

       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

public class DataGridColumnFilter : Control 
{ 
    static DataGridColumnFilter() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(
      typeof(DataGridColumnFilter), new FrameworkPropertyMetadata(typeof(DataGridColumnFilter))); 
    } 

    public DataGridColumnFilter() 
    { 
     this.Loaded += new RoutedEventHandler(DataGridColumnFilter_Loaded); 
    } 

    void DataGridColumnFilter_Loaded(object sender, RoutedEventArgs e) 
    { 
     // here is would be null! 
     var controller = ColumnEntity; 
    } 
    // For some reason this seems to be the only place to access the ColumnEntity 
      protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 
    { 
     if (e.Property == ItemsSourceEntityProperty && e.OldValue != e.NewValue && null != DataGridEntity && ColumnEntity is DataGridColumn) 
     { 
      // here it works fine. The property has a proper value 
       var controller = ColumnEntity; 
     } 

     base.OnPropertyChanged(e); 
    } 

    #region Properties 

    public Query QueryEntity 
    { 
     get { return (Query)GetValue(QueryEntityProperty); } 
     set { SetValue(QueryEntityProperty, value); } 
    } 

    public static readonly DependencyProperty QueryEntityProperty = 
     DependencyProperty.Register("QueryEntity", typeof(Query), typeof(DataGridColumnFilter)); 

    public DataGridColumn ColumnEntity 
    { 
     get { return (DataGridColumn)GetValue(ColumnEntityProperty); } 
     set { SetValue(ColumnEntityProperty, value); } 
    } 

    public static readonly DependencyProperty ColumnEntityProperty = 
     DependencyProperty.Register("ColumnEntity", typeof(DataGridColumn), typeof(DataGridColumnFilter)); 

    public DataGrid DataGridEntity 
    { 
     get { return (DataGrid)GetValue(DataGridEntityProperty); } 
     set { SetValue(DataGridEntityProperty, value); } 
    } 

    public static readonly DependencyProperty DataGridEntityProperty = 
     DependencyProperty.Register("DataGridEntity", typeof(DataGrid), typeof(DataGridColumnFilter)); 

    public IEnumerable ItemsSourceEntity 
    { 
     get { return (IEnumerable)GetValue(ItemsSourceEntityProperty); } 
     set { SetValue(ItemsSourceEntityProperty, value); } 
    } 

    public static readonly DependencyProperty ItemsSourceEntityProperty = 
     DependencyProperty.Register("ItemsSourceEntity", typeof(IEnumerable), typeof(DataGridColumnFilter)); 

    #endregion 
} 

Répondre

0

essayez d'utiliser l'événement OnApplyTemplate au lieu de l'événement chargé

public override void OnApplyTemplate()

0

évaluation Reliure se plus tard dans la processus de chargement après l'ensemble de l'arbre visuel a été construit. Plutôt que de compter sur un seul événement pour collecter des valeurs, utilisez simplement les gestionnaires PropertyChanged sur DependencyProperties, dont vous avez déjà confirmé qu'ils vous donnent les valeurs attendues.

Vous pouvez également simplifier l'utilisation de ColumnEntity ColumnEntity="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Column}"