0

I have this own class :

public class PeriodContainerPanel:StackPanel
{
    public PeriodContainerPanel()
        : base()
    {
        addCollectionsToStackPanel();
    }

    private void addCollectionsToStackPanel()
    {
        this.Children.Clear();


        if (PeriodsList!=null)
        {
            double minutes = PeriodsList.Count * (Properties.Settings.Default.EndTimeSpan - Properties.Settings.Default.StartTimeSpan).TotalMinutes;
            foreach (ObservableCollection<PeriodBase> lst in PeriodsList)
            {
                this.Children.Add(new ChartUserControl(lst) { Minutes = minutes });
            }
        }
    }

    public List<ObservableCollection<PeriodBase>> PeriodsList
    {
        get { return (List<ObservableCollection<PeriodBase>>)GetValue(PeriodsListProperty); } //do NOT modify anything in here
        set { SetValue(PeriodsListProperty, value); addCollectionsToStackPanel(); } //...or here
    }

    public static readonly DependencyProperty PeriodsListProperty =
        DependencyProperty.Register(
        "PeriodsList",  //Must be the same name as the property created above
        typeof(List<ObservableCollection<PeriodBase>>), //Must be the same type as the property created above
        typeof(PeriodContainerPanel), //Must be the same as the owner class
        new UIPropertyMetadata(
            null  //default value, must be of the same type as the property
            ));
}

And i use this DependencyProperty PeriodList in UserControl like this :

<GridViewColumn>
   <GridViewColumn.CellTemplate>
   <DataTemplate>
      <UI:PeriodContainerPanel PeriodsList="{Binding RelativeSource={RelativeSource  Mode=TemplatedParent}, Path=DataContext}" />
   </DataTemplate>
   </GridViewColumn.CellTemplate>
</GridViewColumn>

I check with Convertor is there any getting process (if there is value) yes there is value and it is correct, but its not set to PeriodsList property. What is problem ? P.S if there is any question about code, please tell , i can add

Javidan
  • 566
  • 1
  • 9
  • 25
  • Did you forget the definition of PeriodList property or you just didn't show it here? – Vale Oct 18 '12 at 11:41
  • Oh, sorry. I think the problem is that you call addCollectionsToStackPanel() in the constructor, before binding is completed. That's why PeriodList is null. Try to registe Loaded and call it there. – Vale Oct 18 '12 at 11:58

2 Answers2

0

As @MrDosu suggested, use PropertyChangedCallback on the DependencyProperty. The issue with Callback being static is not such a big deal since you will get a reference to the DependencyObject in the invocation:

private static void ValueChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
  ((MyCustomControl)d).RaiseMyValueChanged(); //Where RaiseMyValueChanged is a private non-static method.
}

Also your use of TemplatedParent and Path=DataContext seems strange. Path should be referring to a property. TemplatedParent is used when defining styles and/or control templates, your XAML snippet is not a control template in a resource, right?

Fredrik Claesson
  • 609
  • 7
  • 12
0

addCollectionsToStackPanel() will not be called when binding occurs. The binding engine uses SetValue directly and that is why you should never do logic like that in the property. (Thats why it says "do NOT modify anything" in the auto generated comment)

Use a PropertyChangedCallback for this scenario: http://msdn.microsoft.com/en-us/library/ms745795.aspx

MrDosu
  • 3,427
  • 15
  • 18
  • i know about CallBack method, but it must be static, and it makes additional code, and i must set other things static to use my method. is it right solution for this ? – Javidan Oct 18 '12 at 12:59
  • If you want to react to the dependency property being changed you basically need to use the callback, yeah. – MrDosu Oct 18 '12 at 13:04