Data Binding to a listbox item template not working - c#

I have the following code. It builds and runs but does not populate the listbox. Can someone spot the mistake?
<Grid>
<ListBox ItemsSource="{Binding Path=questions}" Height="401" HorizontalAlignment="Left" Name="results" VerticalAlignment="Top" Width="260" Margin="0,20,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=question.votes}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
<TextBlock Text="{Binding Path=question.answers}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="Auto" Width="249">
<TextBlock Text="{Binding Path=question.title}" FontWeight="Bold" Background="#FF92F2CD" Height="22" Width="229" Foreground="Black"/>
<TextBlock Text="{Binding Path=question.body}" TextWrapping="Wrap" Height="43" Width="231" Background="#FFEFEFEF" Foreground="Black"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Path=question.tags}" Foreground="#FFFF9C00" Background="#FF4E3D3D" FontWeight="Bold" TextAlignment="Center"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Refresh" Height="22" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="54" />
</Grid>
public class question
{
public string votes { get; set; }
public string answers { get; set; }
public string title { get; set; }
public string body { get; set; }
public string tags { get; set; }
}
public partial class MainWindow : Window
{
ObservableCollection<question> questions = new ObservableCollection<question>();
public MainWindow()
{
questions.Add(new question
{
votes = "2",
answers = "3",
title = "This is a sample title",
body = "This is a sample body text. It should wrap and not look like shit when presented.",
tags = "C#,WPF,XML,JediStyle"
});
this.DataContext = this;
InitializeComponent();
}
}

Binding does not work on fields but on properties.
ObservableCollection<question> questions = new ObservableCollection<question>();
ObservableCollection<question> MyQuestions
{
get { return questions; }
}
And in XAML
ItemsSource="{Binding Path=MyQuestions}"
You also don't have to specify question as a part of path for every binding within particular list item:
Text="{Binding Path=question.tags}" should be Text="{Binding Path=tags}" or even simpler: Text="{Binding tags}"

<ListBox ItemsSource="{Binding Path=questions}" Height="401" HorizontalAlignment="Left" Name="results" VerticalAlignment="Top" Width="260" Margin="0,20,0,0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=votes}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
<TextBlock Text="{Binding Path=answers}" FontSize="15" Padding="5" Background="White" Foreground="Black"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="Auto" Width="249">
<TextBlock Text="{Binding Path=title}" FontWeight="Bold" Background="#FF92F2CD" Height="22" Width="229" Foreground="Black"/>
<TextBlock Text="{Binding Path=body}" TextWrapping="Wrap" Height="43" Width="231" Background="#FFEFEFEF" Foreground="Black"/>
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Text="{Binding Path=tags}" //am not sure from where this tags coming
Foreground="#FFFF9C00" Background="#FF4E3D3D" FontWeight="Bold" TextAlignment="Center"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

I would try to use a ViewModel ...
Good Article
Another Good Article
The two articles highlight the benefits of full binding and go into the NotifyPropertyChanged and commands. Worth a read.

Related

wpf help binding data to controls in TabControl

So I have a TabControl with two TabItems, each TabItem has the same controls on it (8 TextBlocks) and will display data under the same bindings as their counterparts on the other TabItem.
The xaml and cs code that I have is below, but when I try execute it I get this error.
Items collection must be empty before using ItemsSource.
XAML for TabItem Structure
<TabControl Name="tbcIndividualStats" HorizontalAlignment="Left" Height="652" VerticalAlignment="Top" Width="1338" ItemsSouce="{Binding tabcontrolitems}">
<!--Template for all tabs (idea is to have them dynamically created eventually)-->
<!--Content template-->
<TabControl.ContentTemplate>
<DataTemplate>
<Grid>
<!--Border just holds the stuff-->
<Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
<StackPanel Margin="0,0,-1,0">
<TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
<TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
<TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
<TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
<TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
<TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
<TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
<TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
<!--Item Template-->
<TabControl.ItemTemplate>
<DataTemplate>
<Grid>
<!--Border just holds the stuff-->
<Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
<StackPanel Margin="0,0,-1,0">
<TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
<TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
<TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
<TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
<TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
<TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
<TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
<TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</TabControl.ItemTemplate>
<TabItem Header="PlayerName" Background="Transparent" />
<TabItem Header="PlayerName2" Background="Transparent" />
</TabControl>
C# for Binding Data
public class TabItemContent
{
public string Venue { get; set; }
public string TopSpeed { get; set; }
public string DistRun { get; set; }
public string TimeLow { get; set; }
public string TimeMed { get; set; }
public string TimeHigh { get; set; }
public string TimeSprint { get; set; }
public string DistSprint { get; set; }
}
public void foo()
{
//All one line of code
//FileLoadData is a List of another class where all my data is stored
var tabitemcontents = new List<TabItemContent> { new TabItemContent { Venue = FileLoadData[0].Venue, TopSpeed = FileLoadData[0].TopSpeed.ToString(), DistRun = FileLoadData[0].TotalDistance.ToString(), TimeLow = FileLoadData[0].TimeLow.ToString(),
TimeMed = FileLoadData[0].TimeMed.ToString(), TimeHigh = FileLoadData[0].TimeHigh.ToString(), TimeSprint = FileLoadData[0].TimeSprint.ToString(), DistSprint = "null"},
new TabItemContent { Venue = FileLoadData[1].Venue, TopSpeed = FileLoadData[1].TopSpeed.ToString(), DistRun = FileLoadData[1].TotalDistance.ToString(), TimeLow = FileLoadData[1].TimeLow.ToString(),
TimeMed = FileLoadData[1].TimeMed.ToString(), TimeHigh = FileLoadData[1].TimeHigh.ToString(), TimeSprint = FileLoadData[1].TimeSprint.ToString(), DistSprint = "null"}};
//Error here, supposed to add to the TabItems
tbcIndividualStats.ItemsSource = tabitemcontents;
}
I've been looking for a solution for ages and I can't get one to work. I just need to bind that data from FileLoadData[0] and FileLoadData[1] to the two TabItems respectivly.
I would adopt a different strategy:
Add to your model, the name that you want to show in the Header of the Tabitem:
public class TabItemContent
{
public string PlayerName {get; set;} // New Property for the Tabitem Header
public string Venue { get; set; }
public string TopSpeed { get; set; }
public string DistRun { get; set; }
public string TimeLow { get; set; }
public string TimeMed { get; set; }
public string TimeHigh { get; set; }
public string TimeSprint { get; set; }
public string DistSprint { get; set; }
}
Then i'd change the Xaml considering this new attribute:
<TabControl Name="tbcIndividualStats" HorizontalAlignment="Left" Height="652" VerticalAlignment="Top" Width="1338">
<!--Template for all tabs (idea is to have them dynamically created eventually)-->
<!--Content template-->
<TabControl.ContentTemplate>
<DataTemplate>
<Grid>
<!--Border just holds the stuff-->
<Border BorderBrush="#FF53535B" BorderThickness="3" HorizontalAlignment="Left" Height="452" VerticalAlignment="Top" Width="520" Margin="10,135,0,0">
<StackPanel Margin="0,0,-1,0">
<TextBlock Name="txtVenue" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding Venue}" />
<TextBlock Name="txtTopSpeed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TopSpeed}" />
<TextBlock Name="txtDistRun" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding DistRun}" />
<TextBlock Name="txtTimeLow" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeLow}" />
<TextBlock Name="txtTimeMed" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeMed}" />
<TextBlock Name="txtTimeHigh" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeHigh}" />
<TextBlock Name="txtTimeSprint" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding TimeSprint}" />
<TextBlock Name="txtSprintDist" Margin="10,7" FontSize="30" Foreground="White" Text="{Binding SprintDist}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
<!--Item Template-->
<TabControl.ItemTemplate>
<DataTemplate>
<Border>
<Textblock = Text="{Binding PlayerName}"/>
</Border>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
EDIT: the item template is the template for the tabitem button and content template is for its content. Some references here: TabItem.ItemTemplate vs TabItem.ContentTemplate
I've also removed the two TabItem defined inside TabControl.
Remember also to set the ItemsSource -> if you set it in code-behind, remove this line: ItemsSouce="{Binding tabcontrolitems}".
Remove these <TabItem> elements from the XAML:
<TabItem Header="PlayerName" Background="Transparent" />
<TabItem Header="PlayerName2" Background="Transparent" />
You can't both add individual items to the TabControl and use an ItemsSource. It's one way or the other.

filter xaml gridview with combo box

I am just starting off with windows 8 apps development and I want to be able to filter a gridview using the selected value in a combobox
my xaml page code behind
public sealed partial class MainPage : Page
{
public ObservableCollection<Recording> MyMusic = new ObservableCollection<Recording>();
public MainPage()
{
this.InitializeComponent();
// Add items to the collection.
MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live",
new DateTime(2008, 2, 5)));
MyMusic.Add(new Recording("Luka Abrus",
"The Road to Redmond", new DateTime(2007, 4, 3)));
MyMusic.Add(new Recording("Jim Hance",
"The Best of Jim Hance", new DateTime(2007, 2, 6)));
// Set the data context for the combo box.
//ComboBox1.DataContext = MyMusic;
this.DataContext = new CollectionViewSource { Source = MyMusic };
}
}
Class
public class Recording
{
public Recording() { }
public Recording(string artistName, string cdName, DateTime release)
{
Artist = artistName;
Name = cdName;
ReleaseDate = release;
}
public string Artist { get; set; }
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
// Override the ToString method.
public override string ToString()
{
return Name + " by " + Artist + ", Released: " + ReleaseDate.ToString("d");
}
}
Xaml mark up
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ComboBox x:Name="ComboBox1" HorizontalAlignment="Left" Margin="542,108,0,0" VerticalAlignment="Top" Width="360" ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="Artist:" Margin="2" />
<TextBlock Text="{Binding Artist}" Margin="2" />
<TextBlock Text="CD:" Margin="10,2,0,2" />
<TextBlock Text="{Binding Name}" Margin="2" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!--<StackPanel x:Name="RecordingDetails" Margin="542,150,10,30">
<TextBlock Text="{Binding Artist}" FontWeight="Bold" FontSize="30" />
<TextBlock Text="{Binding Name}" FontStyle="Italic" FontSize="30" />
<TextBlock Text="{Binding ReleaseDate}" FontSize="30" />
</StackPanel>-->
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding}"
SelectionMode="None"
IsSwipeEnabled="false" >
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}" Name="test">
<TextBlock Text="{Binding Artist}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Name}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
<TextBlock Text="{Binding ReleaseDate}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,70,0"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
so essentially I just need to filter the gridview dynamically using combo box value selected.
Kindly appreciate help and guidaince please.
This is a msdn example.
You can refer this msdn page link for further details.
UserControl
<UserControl x:Class="TestDataBindingQS.Page2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:TestDataBindingQS"
mc:Ignorable="d"
d:DesignHeight="768" d:DesignWidth="1366">
<UserControl.Resources>
<local:StringFormatter x:Key="StringConverter"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
<StackPanel Width="750" Height="200"
VerticalAlignment="Center" HorizontalAlignment="Center">
<ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
Foreground="Black" FontSize="30" Height="50" Width="750">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="2">
<TextBlock Text="Artist:" Margin="2" />
<TextBlock Text="{Binding Artist}" Margin="2" />
<TextBlock Text="CD:" Margin="10,2,0,2" />
<TextBlock Text="{Binding Name}" Margin="2" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!--The UI for the details view-->
<StackPanel x:Name="RecordingDetails">
<TextBlock Text="{Binding Artist}" FontSize="30" FontWeight="Bold" />
<TextBlock Text="{Binding Name}" FontSize="30" FontStyle="Italic" />
<TextBlock Text="{Binding ReleaseDate,
Converter={StaticResource StringConverter},
ConverterParameter=Released: \{0:d\}}" FontSize="30" />
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
converter class
public class StringFormatter : IValueConverter
{
// This converts the value object to the string to display.
// This will work with most simple types.
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
// Retrieve the format string and use it to format the value.
string formatString = parameter as string;
if (!string.IsNullOrEmpty(formatString))
{
return string.Format(culture, formatString, value);
}
// If the format string is null or empty, simply
// call ToString() on the value.
return value.ToString();
}
// No need to implement converting back on a one-way binding
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And this produces the following output

C# ListBox, different background for each item

I have ListBox in xaml:
<ListBox Name="feedListBox" Height="758" HorizontalAlignment="Center" Margin="0,10,0,0" VerticalAlignment="Top" Width="480" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Background="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Top" Width="480">
<TextBlock FontWeight="Bold" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="#FF000000" Text="{Binding Title.Text, Converter={StaticResource RssTextTrimmer}}" />
<TextBlock Name="feedSummary" Foreground="#FF000000" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary.Text, Converter={StaticResource RssTextTrimmer}}" />
<TextBlock Name="feedPubDate" Foreground="#FF939393" Margin="12,0,10,10" Text="{Binding PublishDate.DateTime}" HorizontalAlignment="Right" />
<Border BorderThickness="1" Height="2" HorizontalAlignment="Center" VerticalAlignment="Top" Width="480" BorderBrush="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can I specify different background for each item?
add a Brush property to your viewmodel and bind the controls in your DataTemplate to it
ViewModel:
using System.ComponentModel;
using System.Windows.Media;
...
public class YourViewModel : INotifyPropertyChanged{
...
private Brush _backgroundCol = Brushes.Red; //Default color
public Brush BackgroundCol
{
get { return _backgroundCol; }
set
{
_backgroundCol = value;
OnPropertyChanged("BackgroundCol");
}
}
...
}
xaml:
<TextBlock Name="feedPubDate" Background="{Binding Path=BackgroundCol}" />
for Information about how to implement the INotifyPropertyChanged interface have a look at: Implementing INotifyPropertyChanged - does a better way exist?
Try this:
XAML:
<ListBox Name="feedListBox" Height="758" HorizontalAlignment="Center" Margin="0,10,0,0" VerticalAlignment="Top" Width="480" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Background="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Top" Width="480">
<Grid Background="{Binding feedTitleBack}">
<TextBlock FontWeight="Bold" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="#FF000000" Text="{Binding Title}"/>
</Grid>
<Grid Background="{Binding feedSummaryBack}">
<TextBlock Name="feedSummary" Foreground="#FF000000" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary}" />
</Grid>
<Grid Background="{Binding feedPubDateBack}">
<TextBlock Name="feedPubDate" Foreground="#FF939393" Margin="12,0,10,10" Text="{Binding PublishDate}" HorizontalAlignment="Right" />
</Grid>
<Border BorderThickness="1" Height="2" HorizontalAlignment="Center" VerticalAlignment="Top" Width="480" BorderBrush="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
CS:
public class data
{
public string Title { get; set; }
public string feedTitleBack { get; set; }
public string Summary { get; set; }
public string feedSummaryBack { get; set; }
public string PublishDate { get; set; }
public string feedPubDateBack { get; set; }
public data() { }
public data(string Title, string feedTitleBack, string Summary, string feedSummaryBack, string PublishDate, string feedPubDateBack)
{
this.Title = Title;
this.feedTitleBack = feedTitleBack;
this.Summary = Summary;
this.feedSummaryBack = feedSummaryBack;
this.PublishDate = PublishDate;
this.feedPubDateBack = feedPubDateBack;
}
}
void loadData()
{
List<data> obj = new List<data>();
obj.Add(new data("Title1", "Red", "Summary1", "Green", "Date", "Blue"));
obj.Add(new data("Title1", "#DD4B39", "Summary1", "#006621", "Date", "#1A0DAB"));
feedListBox.ItemsSource = obj;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
loadData();
}

LongListSelector not binding a array of data Windows Phone 8

I am using LongListSelector and trying to bind an array. But no data is getting displayed. Following is my code please let me know what i am doing wrong?
XAML
<phone:LongListSelector Name="peopleLongListSelector"
ItemsSource="{Binding ComponentData}"
GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemmplate}"
ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
HideEmptyGroups ="true"
IsGroupingEnabled ="true"
LayoutMode="List">
</phone:LongListSelector>
<DataTemplate x:Key="LongListSelectorGroupHeaderTemmplate">
<Border Background="Transparent" Padding="5">
<Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2"
Width="62" Height="62" Margin="0,0,18,0"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontSize="48"
Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>
<DataTemplate x:Key="LongListSelectorItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<Image Width="62" Height="62" Source="{Binding Image}" VerticalAlignment="Top" Margin="0,0,15,0"/>
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>
C#
public class Component
{
public string Guid {get; set;}
public string Name{get; set;}
public Item[] Items{get; set;}
}
public class Item
{
public string Title{get; set;}
public string Subtitle{get; set;}
public string Date{get; set;}
}
public class MainLstViewModel : BaseViewModel
{
private Component[] ComponentData;
public MainLstViewModel()
{
ComponentData = Proxy.GetDataAsync();
}
}
You have some attributes in your Class and binding different in xaml
<phone:LongListSelector Name="peopleLongListSelector"
ItemsSource="{Binding ComponentData}"
GroupHeaderTemplate="{StaticResource LongListSelectorGroupHeaderTemmplate}"
ItemTemplate="{StaticResource LongListSelectorItemTemplate}"
HideEmptyGroups ="true"
IsGroupingEnabled ="true"
LayoutMode="List">
</phone:LongListSelector>
<DataTemplate x:Key="LongListSelectorGroupHeaderTemmplate">
<Border Background="Transparent" Padding="5">
<Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2"
Width="62" Height="62" Margin="0,0,18,0"
HorizontalAlignment="Left">
<TextBlock Text="{Binding Name}"
Foreground="{StaticResource PhoneForegroundBrush}"
FontSize="48"
Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>
<DataTemplate x:Key="LongListSelectorItemTemplate">
<StackPanel Orientation="Horizontal" Margin="4,4">
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Subtitle}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Date}" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</StackPanel>
</DataTemplate>

How to set tooltip with many rows for each (dynamic) listbox item in Silverlight

I would like to set in Silverlight for each item in a ListBox a tooltip with many rows.
In XAML i have a listbox and a button:
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<Button Content="Add" Name="button_add" VerticalAlignment="Top" Width="118" Click="add_Click">
in c#
private void button_add_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<Person> obs1 = new ObservableCollection<Person>();
obs1.Add(new Person(){Name="Name1", Age=1});
obs1.Add(new Person(){Name="Name2", Age=2});
listBox1.ItemsSource = obs1;
// This Line of Code MUST NOT BE USED!! listBox1.DisplayMemberPath = "Name";
}
public class Person
{
public String Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return Name;
}
}
I would like to show for each item the Age as my tooltip.
Edit: Ok, this is the Solution for showing only AGE as tooltip. That is one Line/Row.
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" ToolTipService.ToolTip="{Binding Age}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But what if i want to show a Tooltip with 2 Lines? something like:
Name: Name1
Age: 1
Edit: 3 rows, 2 columns. i also added public String Comment { set; get; } to class Person
<ListBox Height="100" HorizontalAlignment="Left" Margin="24,136,0,0" Name="listBox1" VerticalAlignment="Top" Width="109" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ToolTipService.ToolTip>
<ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Name: " Grid.Row="0" Grid.Column="0" />
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="1"/>
<TextBlock Text="Age: " Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="{Binding Age}" Grid.Row="1" Grid.Column="1"/>
<TextBlock Text="Comment: " Grid.Row="2" Grid.Column="0"/>
<TextBlock Text="{Binding Comment}" Grid.Row="2" Grid.Column="1" TextWrapping="Wrap" />
</Grid>
</ToolTip>
</ToolTipService.ToolTip>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But there is stil a problem. The comment can be short or long, so i would like to make the ROWS/LINES/SPACE for Comment to be variable or else Text is cut off.
You can use any controls for tooltip content:
<ToolTipService.ToolTip>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" />
</StackPanel>
</ToolTipService.ToolTip>
Other possibility would be to use a converter, that returns the Name and Age separated by \r\n.

Categories

Resources