views:

136

answers:

2

All,

I've got a generic list defined in a custom user control.

private List<string> m_AnimationNames = new List<string>();

public List<string> AnimationNames
        {
            get { return this.m_AnimationNames; }
            set { this.m_AnimationNames = value; }
        }

I reference this list in xaml, and populate it, like so.

<local:AnimatedCharacter.AnimationNames>
        <System:String>Walk</System:String>
        <System:String>Run</System:String>
        <System:String>Talk</System:String>
</local:AnimatedCharacter.AnimationNames>

I then try to reference this list elsewhere in code, after InitializeComponent() is called and the list always returns a size of 0 and contains no elements.

Why is this list empty at runtime? What am I missing that is making this list count 0 when I access it in code?

Full Class:

public partial class AnimatedCharacter : UserControl
    {

        private List<string> m_AnimationNames = new List<string>();



        public AnimatedCharacter()
        {
            InitializeComponent();                        
            DoSomething();
        }


        public List<string> AnimationNames
        {
            get { return this.m_AnimationNames; }
            set { this.m_AnimationNames = value; }
        }


        public void DoSomething(){
            Console.WriteLine("Anim: " + AnimationNames.Count);   
        }
    }
}

XAML instance:

<local:AnimatedCharacter x:Name="ac_guy1" Height="315" Width="273" Canvas.Left="-666" Canvas.Top="-99" >            
            <local:AnimatedCharacter.AnimationNames>
                <System:String>Walk</System:String>
                <System:String>Run</System:String>
                <System:String>Talk</System:String>
            </local:AnimatedCharacter.AnimationNames>

</local:AnimatedCharacter>
+3  A: 

Call DoSomething after the control has loaded (wait for the Loaded event). You are calling it in the constructor, before the AnimationNames property has been set via XAML:

public AnimatedCharacter() 
{ 
    InitializeComponent();                         

    this.Loaded += new RoutedEventHandler(OnLoaded);
} 

private void OnLoaded(object sender, RoutedEventArgs e)
{
     this.DoSomething();
}
Michael S. Scherotter
Very nice. Thank you!
csciguy
+2  A: 

Michael has the solution but let me explain what is going on.

When the Xaml parser reaches this part of the Xaml:-

 <local:AnimatedCharacter

It constructs a new instance of AnimatedCharacter which includes therefore the execution of its constructor, the InitialiseComponent and whatever else is in the constructor. Of course at that point none of the attributes have been parsed and assigned to the appropriate properties and also child contents in the Xaml have not been parsed and added to the List.

The Loaded event fires when the whole of the Xaml for the control has been read and the control has been added to the visual tree. Hence if you need to work with the loaded List you need to do so in a Loaded event handler not in the constructor.

AnthonyWJones
Very nice. Thanks Anthony! This clears some things up. I was a bit unsure of the loading there.
csciguy