WPF - Binding to a list within a Listview Item - c#

So I am trying to bind to a list within a ListView item but I can't seem to get the binding correct. If some one could help me with the corrected binding that would be great!
Here is the source you will probably need:
//class that xaml is initially bound to
public partial class UploadMngPanel : Grid
{
....
//initial list to bind to
public ObservableCollection<FinishedAnimeCollection> UploadedAnime
{
get { return uploadedAnime; }
}
}
public class FinishedAnimeCollection
{
...
//second list to bind to
private ObservableCollection<AnimeEpisodeItem> _episodes = new ObservableCollection<AnimeEpisodeItem>();
public ObservableCollection<AnimeEpisodeItem> Episodes
{
get { return _episodes; }
}
}
public class AnimeEpisodeItem
{
public String Title { get; set; }
public DateTime TimeAdded { get; set; }
}
The XAML that I am trying to fix is below
<!-- First list binding here (this works)-->
<ListView Name="finishedView" ItemsSource="{Binding UploadedAnime}">
<ListView.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AnimeExpander.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="AnimeRow">
<DockPanel>
<!-- <Image Height="75" Width="Auto" Source="{Binding Image}" DockPanel.Dock="Left" VerticalAlignment="Top"/> -->
<Expander Template="{StaticResource AnimeExpanderControlTemplate}" Header="{Binding AnimeTitle}">
<Expander.ContentTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1,1,1,1">
<!--Second list binding here (this doesn't work)-->
<ListView ItemsSource="{Binding Path=Episodes}">
<ListViewItem>
<DockPanel>
<TextBlock Text="{Binding Title}" DockPanel.Dock="Left" />
<!--<TextBlock Text="{Binding TimeAdded}" DockPanel.Dock="Right" />-->
</DockPanel>
</ListViewItem>
</ListView>
</Border>
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DockPanel>
</DataTemplate>
</ResourceDictionary>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Width="700" Header="Anime" CellTemplate="{StaticResource AnimeRow}"/>
</GridView>
</ListView.View>
</ListView>
If you need any more source code please let me know. Thanks alot!

Ok so after a bit more fooling around I finally found out how to do it. Apparently this:
<ListView ItemsSource="{Binding Path=Episodes}">
<ListViewItem>
<DockPanel>
<TextBlock Text="{Binding Title}" DockPanel.Dock="Left" />
<!--<TextBlock Text="{Binding TimeAdded}" DockPanel.Dock="Right" />-->
</DockPanel>
</ListViewItem>
</ListView>
Is not valid even though it didn't through and error. When you specify an ItemSource for a list view you cannot use the ListViewItem tag within the ListView. So I reworked my code into the following which works:
<TabItem Header="Finished">
<TabItem.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="AnimeExpander.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate x:Key="EpisodeItem">
<DockPanel Margin="30,3">
<TextBlock Text="{Binding Title}" DockPanel.Dock="Left" />
<WrapPanel Margin="10,0" DockPanel.Dock="Right">
<TextBlock Text="Finished at: " />
<TextBlock Text="{Binding TimeAdded}" />
</WrapPanel>
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="AnimeItem">
<DockPanel Margin="5,10">
<Image Height="75" Width="Auto" Source="{Binding ImagePath}" DockPanel.Dock="Left" VerticalAlignment="Top"/>
<Expander Template="{StaticResource AnimeExpanderControlTemplate}" >
<Expander.Header>
<TextBlock FontWeight="Bold" Text="{Binding AnimeTitle}" />
</Expander.Header>
<ListView ItemsSource="{Binding Episodes}" ItemTemplate="{StaticResource EpisodeItem}" BorderThickness="0,0,0,0" />
</Expander>
</DockPanel>
</DataTemplate>
</ResourceDictionary>
</TabItem.Resources>
<ListView Name="finishedView" ItemsSource="{Binding UploadedAnime, diagnostics:PresentationTraceSources.TraceLevel=High}" ItemTemplate="{StaticResource AnimeItem}" />
</TabItem>

Related

Use different XAML template depending on a binding value

I'm using the following code to display some data in a ListView, which is working fine. What I am wanting to do is show a slightly different template in the list depending on the value of a binding value.
Can anyone give some example code to allow me to do that? I want to show a few more textblocks depending on the value of a binding value called Realtime. In other words if Realtime exists show one template, if it doesn't show another.
Thanks in advance!
<ListView x:Name="list" IsItemClickEnabled="False" Margin="0,300,0,0" SelectionMode="None">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Scheduled}"/>
<StackPanel Grid.Column="1">
<TextBlock TextTrimming="WordEllipsis" Text="{Binding Destination}"/>
<TextBlock TextTrimming="WordEllipsis" Text="{Binding Company}"/>
</StackPanel>
<TextBlock Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Route}"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You can create a DataTemplateSelector to get a different template based on each item
https://marcominerva.wordpress.com/2013/02/18/dynamically-choose-datatemplate-in-winrt/
//MyDataTemplateSelector.cs
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate TextTemplate { get; set; }
public DataTemplate ImageTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
//Here you can cast 'item' and check the RealTime value
if (item is TextItem)
return TextTemplate;
if (item is ImageItem)
return ImageTemplate;
return base.SelectTemplateCore(item, container);
}
}
//XAML
<Page.Resources>
<DataTemplate x:Key="TextDataTemplate">
<Border BorderBrush="LightGray" BorderThickness="1">
<Grid HorizontalAlignment="Left" Width="400" Height="280">
<StackPanel>
<TextBlock Text="{Binding Name}" Margin="15,0,15,20"
Style="{StaticResource TitleTextStyle}"
TextWrapping="Wrap" TextTrimming="WordEllipsis" MaxHeight="40"/>
<TextBlock Text="{Binding Content}" Margin="15,0,15,0" Height="200"
TextWrapping="Wrap" TextTrimming="WordEllipsis"/>
</StackPanel>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="ImageDataTemplate">
<Grid HorizontalAlignment="Left" Width="400" Height="280">
<Border Background=
"{StaticResource ListViewItemPlaceholderBackgroundThemeBrush}">
<Image Source="{Binding Url}" Stretch="UniformToFill"/>
</Border>
<StackPanel VerticalAlignment="Bottom"
Background=
"{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Name}"
Foreground=
"{StaticResource ListViewItemOverlayForegroundThemeBrush}"
Style="{StaticResource TitleTextStyle}"
Height="40" Margin="15,0,15,0"/>
</StackPanel>
</Grid>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
TextTemplate="{StaticResource TextDataTemplate}"
ImageTemplate="{StaticResource ImageDataTemplate}">
</local:MyDataTemplateSelector>
</Page.Resources>
<GridView
x:Name="itemGridView"
Padding="116,137,40,46"
ItemTemplateSelector="{StaticResource MyDataTemplateSelector}" />

Observable Collection to Tabcontrol binding

<TabControl HorizontalAlignment="Stretch" TabStripPlacement="Left" Margin="10,20,0,0" Name="tabControl2" ItemsSource="{Binding NotesObs}" VerticalAlignment="Stretch" MinHeight="80">
<TabItem Header="Contract Read and understood, proposal letter read and understood." Name="tabItem2" FontSize="14" IsEnabled="True">
<Grid>
<Border Name="b_desc"/>
<TextBox HorizontalAlignment="Stretch" Margin="0" Name="textBox5" Text="{Binding ContractText}"
VerticalAlignment="Stretch" FontSize="12" TextWrapping="Wrap"
AutoWordSelection="True" VerticalScrollBarVisibility="Auto"
AcceptsReturn="True"
Width="{Binding ElementName=b_desc, Path=ActualWidth}"
Height="{Binding ElementName=b_desc, Path=ActualHeight}"
MaxWidth="{Binding ElementName=b_desc, Path=Width}"
MaxHeight="{Binding ElementName=b_desc, Path=Height}" />
</Grid>
</TabItem>
</TabControl>
Above is my Xaml and the name of my ObsCollection is
public ObservableCollection<NotesDisplay> NotesObs { get; set; }
I have declared properly the ContractText column in the NotesDisplay Model. I cant get this to bind for some reason but this works in a datagrid. Can someone explain what I am doing wrong in my XAML?
Thanks
Edit: I have viewed the linked solution but tabs arent showing up when I run the program. They do showup in the display in xaml
<UserControl x:Class="CAT_Application_WPF.UI.NotesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CAT_Application_WPF.UI"
xmlns:viewModel="clr-namespace:CAT_Application_WPF.ViewModel"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
xmlns:oxy="http://oxyplot.org/wpf"
d:DesignHeight="640">
<Grid Margin="0,0,0,0" Background="{DynamicResource {x:Static SystemColors.GradientActiveCaptionBrushKey}}" d:DataContext="{d:DesignInstance viewModel:NotesPageViewModel}" >
<Grid.RowDefinitions>
<RowDefinition Height="60*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"></ColumnDefinition>
<ColumnDefinition Width="400"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TabControl HorizontalAlignment="Stretch" ItemsSource="{Binding NotesObs}" TabStripPlacement="Top" x:Name="_tabControl" VerticalAlignment="Stretch" MinHeight="80" Grid.ColumnSpan="2" Margin="121,28,279,-28">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock Text="{Binding ContractText}"/>
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<TextBlock>
This is <TextBlock Text="{Binding EMSText}"/>
</TextBlock>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</Grid>
</UserControl>
Now it's quite ok but you must remove your TextBlock inside another TextBlock stuff.
You can change
<TextBlock>
<TextBlock Text="{Binding ContractText}"/>
</TextBlock>
to
<TextBlock Text="{Binding ContractText}"/>
And
<TextBlock>
This is <TextBlock Text="{Binding EMSText}"/>
</TextBlock>
to something similar to
<StackPanel Orientation="Horizontal">
<TextBlock>This is</TextBlock>
<TextBlock Text="{Binding EMSText}"/>
</StackPanel>

ItemTemplate definition in another UserControl

I have the following usercontrol to define my general control-layout:
<UserControl>
<DockPanel LastChildFill="False">
<ListView DockPanel.Dock="Left"
ItemsSource="{Binding FoundResults}"
SelectedItem="{Binding SelectedItem}"
ItemTemplate="{DynamicResource FoundResultsStyle}"/>
<ContentControl DockPanel.Dock="Top"
Name="WinSock"
Content="{Binding ElementName=BaseWindowUserControl, Path=SpecificView}" />
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem Content="{Binding StatusBarText, Mode=OneWay}" />
</StatusBar>
</DockPanel>
</UserControl>
Every window should have a ListView on the left side as you can see.
I need a way to define the ItemTemplate in the concrete userControl.
Person-Usercontrol:
<UserControl.Resources>
<DataTemplate x:Key="FoundResultsStyle" DataType="{x:Type Pocos:Person}">
<StackPanel>
<TextBlock Text="{Binding Lastname}"/>
<TextBlock Text="{Binding Firstname}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
The ListView doesn't use my Template which I have defined in my 'concrete' usercontrol. Is there a way to achieve this?
Thank you in advance!
Can you do something like this, so that the DataType, as it changes, will select the correct template?
<UserControl>
<UserControl.Resources>
<DataTemplate DataType="{x:Type Pocos:Person}">
...
</DataTemplate>
<DataTemplate DataType"{x:Type Pocos:Dog}">
...
</DataTemplate>
</UserControl.Resources>
<DockPanel LastChildFill="False">
<ListView
DockPanel.Dock="Left"
ItemsSource="{Binding FoundResults}"
SelectedItem="{Binding SelectedItem}"/>
<ContentControl
DockPanel.Dock="Top"
Name="WinSock"
Content="{Binding ElementName=BaseWindowUserControl, Path=SpecificView}" />
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem Content="{Binding StatusBarText, Mode=OneWay}" />
</StatusBar>
</DockPanel>
</UserControl>

How todo nested Databinding with Windows Phone (Pivot and ListBox)

I am pretty new in the usage of the DataBinding concept in Windows Phone. I am trying to bind a Pivot page with a list of items, as well as a ListBox in each PivotItem with another list (of criterias). I have a Page with the following XAML:
<phone:Pivot Name="ItemsPivot" Title="MY APPLICATION">
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel Margin="12,17,0,28">
<ListBox Name="CriteriasListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding Name}"/>
<tk:Rating />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
I then try to specify the ItemSource of each binded control in the C# code like this:
...
ItemsPivot.ItemsSource = ItemList;
CriteriasListBox.ItemsSource = CriteriaList; // <-- CriteriasListBox not accessible !!
...
But there is an error stating that "the name 'CriteriasListBox' does not exist in the current context"... As I mention, I am pretty new with this technology.
Can I have some advice, solution or resources on how do make this nested binding work?
Thank you !
Do like this,
<UserControl.Resources>
<DataTemplate x:Key="MyPivotItemTemplate">
<controls:PivotItem Header="first" >
<ListBox x:Name="CriteriasListBox" Margin="0,0,12,0" ItemsSource="{Binding CriteriaList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
</DataTemplate>
</UserControl.Resources>
Then in your pivot
<Pivot ItemsTemplate="{StaticResource MyPivotItemTemplate}" Items="{Binding ItemList}"
One of the ways if you have different criteria list for different items is to add criteria list property to your PivotItemViewModel. Your c# code will look like this
ItemsPivot.ItemsSource = ItemList;
where every item in ItemList contains CriteriaList. Your xaml code will look like
<phone:Pivot Name="ItemsPivot" Title="MY APPLICATION">
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel Margin="12,17,0,28">
<TextBlock Name="PivotTextBlock" Text="{Binding Name}"/>
<ListBox ItemsSource="{Binding Criterions}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<TextBlock Name="ListTextBlock" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
Binding for PivotTextBlock retrieves Name property from the PivotItemViewModel. Binding for ListTextBlock retrieves Name property from Criteria.
If criteria list the only in your application here is a good start
Here is another good way I found...
http://www.codeproject.com/Articles/47229/A-LINQ-Tutorial-WPF-Data-Binding-with-LINQ-to-SQL
Here is a code snippet:
<DataTemplate DataType="{x:Type LINQDemo:Category}">
<Border Name="border" BorderBrush="ForestGreen"
BorderThickness="1" Padding="5" Margin="5">
<StackPanel>
<TextBlock Text="{Binding Path=Name}"
FontWeight="Bold" FontSize="14"/>
<ListView ItemsSource="{Binding Path=Books}"
HorizontalContentAlignment="Stretch" BorderThickness="0" >
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Click="LoadIndividualBook"
CommandParameter="{Binding}"
ToolTip="Display book details">
<TextBlock Text="{Binding Path=Title}"/></Hyperlink>
...

Binding design time data collections in Blend 2013 for Windows Store App

I'll try and provide as much information here as possible but let me prefix it by saying I'm not confident of my knowledge of regular data sources never mind design time data in Blend. My runtime works fine and displays grouped items in the grid view. When viewing in Blend I get nothing and I would like to display some sample data that does the same as the runtime. Is it possible to achieve this? Also if I've gone wrong and over complicated the runtime data sources please feel free to suggest changes.
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="ScoreAlerts.ItemsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
...snip...>
<CollectionViewSource
x:Name="itemsViewSource"
IsSourceGrouped="true"
Source="{Binding Items}"/>
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick" FontFamily="Global User Interface" FontWeight="Light" Margin="0,0,10,0">
<GridView.Resources>
<!-- Grid-appropriate 250 pixel square item template as seen in the GroupedItemsPage and ItemsPage -->
<DataTemplate x:Key="GridItem">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{x:Null}">
<Image Source="{Binding Image}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{StaticResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{StaticResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextStyle}" Height="60" Margin="15,0,15,0"/>
<!-- <TextBlock Text="{Binding Subtitle}" Foreground="{StaticResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/> -->
</StackPanel>
</Grid>
</DataTemplate>
</GridView.Resources>
<GridView.ItemsSource>
<Binding Source="{StaticResource itemsViewSource}"/>
</GridView.ItemsSource>
<!-- Item Template -->
<GridView.ItemTemplate>
<StaticResource ResourceKey="GridItem"/>
</GridView.ItemTemplate>
<!-- Item Panel Template -->
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="4"
HorizontalAlignment="Left"
VerticalAlignment="Center" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0">
<TextBlock Text="{Binding Key}"
Style="{StaticResource PageSubheaderTextStyle}"
Margin="8 4 0 10" />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0 0 40 0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
in the code I have this
this.DefaultViewModel["Items"] = ScoreDataSource.GetGroups("AllGroups")
And my ScoreDataSource has the following
public sealed class ScoreDataSource
{
public static ScoreDataSource _ScoreDataSource = new ScoreDataSource();
private ObservableCollection<ScoreDataGroup> _allGroups = new ObservableCollection<ScoreDataGroup>();
public ObservableCollection<ScoreDataGroup> AllGroups
{
get { return this._allGroups; }
}
public static IEnumerable<object> GetGroups(string uniqueId)
{
if ( uniqueId == "AllGroups" )
{
var query = from item in _ScoreDataSource.AllGroups
orderby item.Country
group item by item.Country into g
select g;
return query;
}
else
{
return _ScoreDataSource.AllGroups;
}
}

Categories

Resources