WPF how to bind a tabitem with a list - c#

I have the following problem:
i have some data loaded in my application, that need to be put in a tab control.
The data is in the format:
class objectType1
{
string property_1;
string prorerty_2;
}
class mainObject
{
string mainProperty_1;
string mainProperty_2;
List<objectType1> objectsList;
}
and all the data is loaded in an object of type
List<mainObject> myListofObjects
So far i managed to create the tabitems with respect to myListofObjects item
(ie if the list has 5 objects, 5 tabs are created with the header containing the information mainProperty_1 and mainProperty_2)
now i need to add the data contained in each objectsList into their respective tab...
the mainProperty_1 represents an image, which must be loaded...
<TabControl x:Name="_DataList" Margin="10">
<!-- Header -->
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="18" Source="{Binding mainProperty_1/>
<TextBlock Text="{Binding mainProperty_2}" Margin="2,0,0,0" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<!-- Content -->
<TabControl.ContentTemplate>
<DataTemplate x:Name="objectDataTemplate">
<Grid Margin="5">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding property_1}" ToolTip="{Binding property_2}" IsHitTestVisible="false" Stretch="Uniform"/>
</StackPanel>
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
I pass the data to the tabcontrol in code behind with
_DataList.ItemsSource = myListofObjects;
this is not working for the content...
the header loads just fine (both image and the text...)
anyone has any idea how to do it?
Thanks a lot!

your ContentTemplate seems to be wrong:
<TabControl x:Name="_DataList" Margin="10">
<!-- Header -->
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="18" Source="{Binding mainProperty_1/>
<TextBlock Text="{Binding mainProperty_2}" Margin="2,0,0,0" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<!-- Content -->
<TabControl.ContentTemplate><!-- its bound to one mainObject -->
<DataTemplate x:Name="objectDataTemplate">
<!-- if you wanna bind to something from your objectsList you have to threat it like a list, cause it is :) -->
<ListBox Itemssource={Binding objectsList}>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type objectType1}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding property_1}" ToolTip="{Binding property_2}" IsHitTestVisible="false" Stretch="Uniform"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>

1) Have you tried to connect to list via binding?
var b = new Binding("myListofObjects");
BindingOperations.SetBinding(_DataList, ItemsControl.ItemsSourceProperty, b);
2) If you're using binding, have you set appropriate DataContext?

Related

How to change value of control inside pivot datatemplate on listpicker_selectedIndexChagned event

<phone:Pivot Title="Bank" x:Name="pivotBank"
ItemsSource="{Binding PivotItems}">
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding StrBankName}"/>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel>
<toolkit:ListPicker x:Name="listPickerAccountNumber" SelectionChanged="listPickerAccountNumber_SelectionChanged"
ItemsSource="{Binding listAccountDetails}" >
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StrAccountNumber}" />
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
<toolkit:ListPicker.FullModeItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding StrAccountNumber}" />
</DataTemplate>
</toolkit:ListPicker.FullModeItemTemplate>
</toolkit:ListPicker>
<TextBlock Text="Account Detail"></TextBlock>
<TextBlock Name="textBlockAccountNumber" Text="{Binding StrAccountNumber}"></TextBlock>
<TextBlock Name="textBlockBalance" Text="{Binding DblBalance}"></TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
Above pivot control contains headers as bank names and pivot datatemplate contains list of accounts. I want to change the control values of textBlockAccountNumber and textBlockBalance on SelectedIndexChanged event of listPicker.
My question is, is there any way to find control by name from the pivot. I used INotifyPropertyChanged Interface and implemented event with handler but not able to get the rid of it.

How to bind a list of list to a ListView control

I have The following structure
QPage class Object contains a List<List<QLine>>
QLine object contains List<Qword>
every list of words constructs a line and every list of lines consists a group(paragraph) and every list of paragraphs consists a page.
I want to bind the page to structure like this in XAML
<ListView>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<TextBlock>
</TextBlock>
</StackPanel>
</StackPanel>
</ListView>
where each item of the ListView is a paragraph(List<QLine>) and each vertical stack panel holds an item of the List<QLine> and each item of the horizontal stack panel holds an item of the List<Qword> and the texblock is bound to Qword.text property. I have no idea how to do such binding from the XAML code.
Hopefully I did not miss some list but this should work. Basically it's a ListBox that hosts List<List<QLine>> (called it QPageList). Then you have ItemsControl that hosts each List<QLine> in vertical panel and finally there is another ItemsControl that hosts List<Qword> from QLine (called it QwordList) where each QWord is displayed as TextBlock on horizontal StackPanel
<!-- ItemsSource: List<List<QLine>>, Item: List<QLine> -->
<ListBox ItemsSource="{Binding QPageList}">
<ListBox.ItemTemplate>
<DataTemplate>
<!-- ItemsSource: List<QLine>, Item: QLine -->
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- ItemsSource: QLine.List<QWord>, Item: QWord -->
<ItemsControl ItemsSource="{Binding QwordList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- Item: QWord -->
<TextBlock Text="{Binding text}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What you are looking for is ListView.ItemTemplate. Basically, you need to provide your list with a way to understand the nested data structure of your rows.
Here is a good tutorial to get you started on ItemTemplates.
Once your list has an item template then you just bind the ListView directly to your data source and that's it.
Hopefuly this will prove helpful. Taken from here
Authors (list)
- - Name
- - Books (list)
| - - Title
| - - Contents
Sample code :
<Window.Resources>
<DataTemplate x:Key="ItemTemplate1">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="ItemTemplate2">
<StackPanel>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource AuthorDataSource}}">
<ListBox x:Name="AuthorList" ItemTemplate="{DynamicResource ItemTemplate1}" ItemsSource="{Binding Authors }" >
<ListBox x:Name="BookList" DataContext="{Binding SelectedItem, ElementName=AuthorList}" ItemsSource="{Binding Books }" ItemTemplate="{DynamicResource ItemTemplate2}" />
<TextBlock x:Name="BookContent" DataContext="{Binding SelectedItem, ElementName=BookList}" Text="{Binding Contents }" />
</Grid>
Forward to what Alex is saying, it'd be a good idea to Encapsulate (If that's the correct word here) the object within classes, i.e.:
public class Page
{
public List<Paragraph> Paragraphs { get; set; }
}
public class Paragraph
{
public List<QWord> Sentences { get; set; }
}
public class Sentence
{
public List<QWord> Words { get; set; }
}
That'd help when you bind data in your XAML, i.e. if you look at the tutorial which Alex provided:
<TextBlock Text="Name: " />
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Age}" FontWeight="Bold" />
<TextBlock Text=" (" />
<TextBlock Text="{Binding Mail}" TextDecorations="Underline" Foreground="Blue" Cursor="Hand" />
<TextBlock Text=")" />
Hope that helps you.

retrieving binded text from xaml in c#

I have my xaml code as :
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ToggleSwitch Name="toggle3" Header="{Binding name}" Height="120" HorizontalAlignment="Left" Margin="35,20,0,0" VerticalAlignment="Center" Width="440" Content="{Binding descrip}" Checked="toggleSwitch1_Checked" Unchecked="toggleSwitch1_Unchecked" Tap="toggleSwitch1_Tap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
Now i want to retrieve toggleswitch(toggle 3)'s header text in c# code. How can that be done?
When you create a data binding like you did, it should automatically update the variable you bound it to, name
Assuming you have a proper collection to serve as the ItemsSource Binding
the xaml would write as follows:
<ListBox x:Name="SecondListBox" Margin="0,0,-12,0" ItemsSource="{Binding Path=ItemsCollection}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<toolkit:ToggleSwitch Name="toggle3" Header="{Binding Name,Mode=TwoWay}" Height="120" HorizontalAlignment="Left" Margin="35,20,0,0" VerticalAlignment="Center" Width="440" Content="{Binding descrip}" Checked="toggleSwitch1_Checked" Unchecked="toggleSwitch1_Unchecked" Tap="toggleSwitch1_Tap"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You'll have to provide a property named ItemsCollection of type IEnumerable<TModel> in your DataContext
where TModel class shouldcontain Name property
This should put you on the right path to access elements inside of ItemTemplate.Probably that's what your looking for.
http://dotbay.blogspot.in/2009/09/accessing-controls-in-wpf-itemtemplate.html

Different Object-Types in Grid- or ListView

I'm currently trying to figure out how to show different types of objects in a GridView, look at this Pic for example:
the last element on the right side is different than the other elements, so if i bind an observablecollection to the GridView, how can i say that the last element is shown up in anohter layout.
currently I'm using this XAML-Code
<GridView x:Name="startView" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="2" SelectionMode="None" Width="Auto">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" MaximumRowsOrColumns="2" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
and this Code in the Back:
ObservableCollection<Movie> recentlyStarted = await Api.RecentlyStarted(3);
startView.DataContext = recentlyStarted;
but I have currently no clue how to let the last element show up in a different style
The easy way would be to have the two types of object as different classes (e.g. MoviePicStyle + MoviePlainStyle. Then move your DataTemplate out of the GridView, so that each object is picked up by type,
e.g.
<Window.Resources>
<DataTemplate DataType="{x:Type ViewModel:MoviePicStyle}">
<StackPanel>
<TextBlock x:Name="DetailTitle" Height="74" Text="{Binding Title}" />
<Image x:Name="Image" Height="Auto" Width="Auto" Margin="0" Stretch="None" Source="{Binding LocalCoverUrl}" Visibility="Collapsed" />
</StackPanel>
<DataTemplate DataType="{x:Type ViewModel:MoviePlainStyle}">
...Different View...
</DataTemplate>
</Window.Resources>
<GridView...
Use template selector property of gridview and depending upon the type of object select the template. I did the same in my project. you need to write your own DataTemplateSelector.
I referred below link
http://babaandthepigman.wordpress.com/2012/02/08/datatemplateselector-winrt/

databinding tooltip in listbox

I am working with binding an xml structure to a listbox. I am quite confused hoe to do this.How to put a datatemplate inside a datatemplate or i need to use a hirarchialdatatemplate...for example from the xml, I want to display the Make Name of the cars in a list box and i want to show the corresponding Suvs's as a tooltip or contextmenu.How to do this..please help..any input will be highly helpfull..my xml file structure is as given below
<XmlDataProvider x:Key="src">
<x:XData>
<Automobiles>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>Audi</MakeName>
<Suvs>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
<SuvId>Item1</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobiles>
</x:XData>
</XmlDataProvider>
I modified your XML format to support multiple Automobile groups:
<XmlDataProvider x:Key="src">
<x:XData>
<Automobiles xmlns="">
<Automobile>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>Audi</MakeName>
<Suvs>
<SuvId>audiItem1</SuvId>
<SuvId>audiItem2</SuvId>
<SuvId>audiItem3</SuvId>
<SuvId>audiItem4</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobile>
<Automobile>
<Id>24</Id>
<Category>Cars</Category>
<MakeName>BMW</MakeName>
<Suvs>
<SuvId>bmwItem1</SuvId>
<SuvId>bmwItem2</SuvId>
<SuvId>bmwItem3</SuvId>
<SuvId>bmwItem4</SuvId>
</Suvs>
<IsPanel>1</IsPanel>
<IsFav>1</IsFav>
</Automobile>
</Automobiles>
</x:XData>
</XmlDataProvider>
I hooked up both a context menu and a tooltip.
Below is how I wired up the bindings:
<ItemsControl ItemsSource="{Binding Source={StaticResource src}, XPath=/Automobiles/Automobile}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal">
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding XPath=Suvs}">
<ContextMenu.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SUV ID: " />
<TextBlock Text="{Binding XPath=SuvId}" />
</StackPanel>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</StackPanel.ContextMenu>
<StackPanel.ToolTip>
<ListBox ItemsSource="{Binding XPath=Suvs/SuvId}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SUV ID: " />
<TextBlock Text="{Binding InnerText, StringFormat={}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel.ToolTip>
<TextBlock Text="Make: " />
<TextBlock Text="{Binding XPath=MakeName}" />
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>

Categories