tags:

views:

39

answers:

3

Hi there,

For some reason I have to initialize the ListBox items in behind code, the reason is too complication to tell.

The LoadFamily() is called during WPF UserControl show up.

public void LoadFamily()
{
    DataTemplate listItemTemplate = this.FindResource("ManDataTemplate") as DataTemplate;

    foreach (Person man in family)
    {
        ListBoxItem item = new ListBoxItem();

        item.DataContext = man;
        item.ContentTemplate = listItemTemplate;
        // other initialize for item object
        this.ActivityList.Items.Add(item);
    }
}

In my xmal file, I define a DataTemplate.

<DataTemplate x:Key="ManDataTemplate" DataType="{x:Type local:Person}">
    <TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>

But the ListBox only contains empty text block, the person's Name doesn't not display. I don't know why, maybe the data binding is wrong, but how to do it in behind code.

Thanks for your any help! (WPF 3.5 or 4.0)

/////////////////////////////////////////////////////////////

Thanks for all your help. I found where I was wrong. I should not add ListBoxItem into ActivityList.Items, one is UIElement, the other is >DataCollection. They are two different thing.

I should modify the code as follow:

foreach (Person man in family)
{
    this.ActivityList.Items.Add(man);
    ListBoxItem item = this.ActivityList.ItemContainerGenerator.ContainerFromItem(man) as ListBoxItem;
    item.ContentTemplate = listItemTemplate;
    // other initialize for item object
}
+1  A: 

I don't see the benefit of creating the listboxitems manually. Just set the ItemsSource of the Listbox to the list of person (family).

Wouter Janssens - Xelos bvba
The benefit is hidden in // other initialize for item object, which I comment out. There are too much code in there. :(
Chuanyu Wang
I still think that it is better to set the ItemsSource of the ListBox to the list and then just use your datatemplate from the XAML. Then it would be automatically use the correct DataContext for each Item an will the Name property be read
Wouter Janssens - Xelos bvba
I tried as you said, it took me some time. I have to convert lots of code into xmal, which is too hard to understand for other people.
Chuanyu Wang
A: 

You need to just set the ItemTemplate of your ListBox not the ContentTemplate of each control

as below

public partial class Window1 : Window { List family = new List(); public Window1() { family.Add(new Person() { Name = "Saurabh" }); family.Add(new Person() { Name = "Sumit" }); family.Add(new Person() { Name = "XYZ" });

        InitializeComponent();

       // ActivityList.ItemContainerGenerator.ItemsChanged += new System.Windows.Controls.Primitives.ItemsChangedEventHandler(ItemContainerGenerator_ItemsChanged);

        LoadListBox();


    }

    public void LoadListBox()
    {
        DataTemplate listItemTemplate = this.FindResource("ManDataTemplate") as DataTemplate;
        ActivityList.ItemTemplate = listItemTemplate;
        foreach (Person man in family)
        {
            ListBoxItem item = new ListBoxItem();

            //item.DataContext = man;

            // item.ContentTemplate = listItemTemplate;

            // other initialize for item object 
            ActivityList.Items.Add(man);
            //listItemTemplate.LoadContent();

        }





    }


}

public class Person
{
    public string Name { get; set; }


}
saurabh
Thank for you suggestion. It works, but lost all my // other initialize for item objectThere are some code, e.g. item.Width = runtimeWidth; item.Selected += new RoutedEventHandler(item_Selected); item.Unselected += new RoutedEventHandler(item_Unselected); item.MouseEnter += new MouseEventHandler(item_MouseEnter);
Chuanyu Wang
A: 

There could be binding error. That's the reason why the textblock is empty. Check the Output window of VisualStudio, it will display the binding errors if exist.

HTH

Avatar
After double check the Output, I found out where I was wrong. I have update my question. Thank you.
Chuanyu Wang