1
votes

I want to show a list in Windows Phone 8.1 app. I have added listview and created item template.

 <ListView x:Name="history" HorizontalAlignment="Left" Height="397" VerticalAlignment="Top" Width="381">
                    <ListView.Resources>
                        <DataTemplate x:Key="myCell">
                            <Grid x:Name="myGrid" Height="161" Width="389">
                                <TextBlock x:Name="title" HorizontalAlignment="Left" Margin="34,13,0,0" TextWrapping="Wrap" Text="Title" VerticalAlignment="Top" Height="52" Width="170" FontSize="48"/>
                                <TextBlock x:Name="content" HorizontalAlignment="Left" Margin="34,70,0,0" TextWrapping="Wrap" Text="content" VerticalAlignment="Top" Height="81" Width="345" FontSize="36"/>
                            </Grid>
                        </DataTemplate>
                    </ListView.Resources>
                    <ListView.ItemTemplate>
                        <StaticResource ResourceKey="myCell"/>
                    </ListView.ItemTemplate>
                </ListView>

I want to add items programmically. Something like that

myCell mm = new myCell();
mm.title.Text = "title";
mm.content.Text = "content";
history.Items.Add(mm);

But I can't access myCell. Anybody can help me?

2

2 Answers

2
votes

Since you are using ItemTemplate you need to create and add items to your ListView using Model.

public class MyModel
{
    public string title {get; set;}
    public string content {get; set;}
}

And then add items just like this:

var item = new MyModel();
item.title = "some title";
item.content = "some content";

history.Add(item);

EDIT

Actually best way is to create ObservableCollection<T> and set it as ItemsSource of you ListView somewhere in code. For example you may use Loaded event of your ListView:

history_Loaded(object sender, RoutedEventArgs e)
{
    var historyCollection = new ObservableCollection<MyModel>();
    history.ItemsSource = historyCollection;
}

Then just add items to this ObservableCollection and they will be displayed as it will report to ListView when it will be changed.

And your TextBlock must define Text property via binding:

<TextBlock Text="{Binding title}"/>

To learn more about ObservableCollection<T> and its difference from List<T> you may want to read this - http://www.codeproject.com/Articles/42536/List-vs-ObservableCollection-vs-INotifyPropertyCha.

0
votes

Data binding has two ends: you need to provide the data in your code behind and you need to bind to it from the Xaml. If you do only one then there is no connection.

To provide the data from the code you need to create a collection of data objects and place it in a context that the ListView can see. We can either set this directly to the ListView's ItemsSource or we can bind the ItemsSource to the ListView's DataContext. Where you choose depends on how far you want this data to be shared. Often you'll set one overall DataContext for the Page and let the ListView bind to a subset of it, but for simplicity let's just set it to the ListView's DataContext:

class myCell
{
    public string Title { get; set; }
    public string Content { get; set; }
}

public sealed partial class MainPage : Page
{
    // Create a collection of myCells. ObservableCollection will fire
    // change notifications so we can add new cells later and the binding
    // will update
    ObservableCollection<myCell> myCells = new ObservableCollection<myCell>();
    public MainPage()
    {
        this.InitializeComponent();

        this.NavigationCacheMode = NavigationCacheMode.Required;

        // Generate some dummy data
        for (int i=0;i<100;i++)
        {
            myCells.Add(new myCell() { Title = "Cell " + i, Content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." });
        }

        // Set the cells to the Page's DataContext. All controls on 
        // the page will inherit this.
        this.DataContext = myCells;
    }
}

Once we have data we need to bind to it from the Xaml. Your existing template has TextBlocks for the Title and the Content, but it sets the Text properties explicitly rather than binding to the listed objects. To fix that we need to change the TextBlocks' Text properties to bind to the Title and Context of the item represented by the template. The original template was too big to fit well, so I've reorganized it a bit. Note also the ItemsTemplate={Binding} addition to the ListView:

<ListView x:Name="history" ItemsSource="{Binding}">
    <ListView.Resources>
        <DataTemplate x:Key="myCell">
            <StackPanel>
                <TextBlock x:Name="title" HorizontalAlignment="Left"  TextWrapping="Wrap" Text="{Binding Title, Mode=OneTime}" VerticalAlignment="Top" Style="{StaticResource TitleTextBlockStyle}" />
                <TextBlock x:Name="content" HorizontalAlignment="Left"  TextWrapping="Wrap" Text="{Binding Content, Mode=OneTime}" VerticalAlignment="Top" Style="{StaticResource BodyTextBlockStyle}"  />
            </StackPanel>
        </DataTemplate>
    </ListView.Resources>
    <ListView.ItemTemplate>
        <StaticResource ResourceKey="myCell"/>
    </ListView.ItemTemplate>
</ListView>

For more information see the Data binding overview (XAML) on MSDN, in particular the Binding to Collections section.