I want to design a tabcontrol. Each tabitem has a grid. Lets say grid is databound to list of object. Now how do i bind the tabcontrol to.
Below shown is the class
Class GridData
{
String Name;
string Id;
string location
}
Class TabItems
{
string tabName;
List<GridData> ls;
}
Whats the best way to implementing the databinding
Say you have these 2 classes:
public class GridData
{
public string Name { get; set; }
public string Id { get; set; }
public string Location { get; set; }
}
public class TabItems
{
public string tabName { get; set; }
public List<GridData> ls { get; set; }
}
and you set TabControl.ItemsSource to List<TabItems> then your XAML for that TabControl can look something like this:
<TabControl>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding tabName}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding ls}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Id, StringFormat='{}Id: {0}'}"/>
<TextBlock Text="{Binding Path=Name, StringFormat='{}Name: {0}'}"/>
<TextBlock Text="{Binding Path=Location, StringFormat='{}Location: {0}'}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
You specify 2 DataTemplates. TabControl.ItemTemplate for header and TabControl.ContentTemplate for content which in this example is ItemsControl to display ls
Related
So I have an ``ObservableCollection which I'm binding to a Pivot control. This ObservableCollection has a child that is also an ObservableCollection and I'm trying to bind a GridView in each Pivotitem's body.
I've tested my code-behind to ensure the collections are populated i.e.
// Level 1 ObservableCollection
foreach (var dchallenge in ChallengesList)
{
// Level 2 ObservableCollection
Debug.WriteLine(dchallenge.Name);
foreach (var dactivity in dchallenge.Activities)
{
Debug.WriteLine(dactivity.Name);
}
}
And its output is as expected.
For reference, my model is as follows:
public class Challenge
{
public string Type { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Slug { get; set; }
public string Image { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ObservableCollection<Activity> Activities { get; set; }
public class Activity
{
public string Name { get; set; }
public string Description { get; set; }
public long Hash { get; set; }
}
}
And finally, my view:
<Pivot x:Name="Items" ItemsSource="{x:Bind ChallengesList, Mode=OneWay}" Margin="20,417,0,0">
<Pivot.HeaderTemplate>
<DataTemplate x:DataType="data:Challenge">
<TextBlock Text="{Binding Name, Mode=OneWay}" FontWeight="Normal" FontSize="16"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate x:DataType="data:Challenge">
<StackPanel Margin="0,20,0,0" HorizontalAlignment="Left">
<TextBlock Text="{Binding Description, Mode=OneWay}" MaxWidth="300" TextWrapping="WrapWholeWords"/>
<TextBlock Text="Activities" FontWeight="Medium" MaxWidth="300" Margin="0,20,0,0"/>
<!--<GridView DataContext="{Binding}" ItemsSource="{x:Bind Activities}" SelectionMode="None"
IsItemClickEnabled="False" IsSwipeEnabled="False" CanDragItems="False"
HorizontalAlignment="Left" Margin="0,70,0,0" VerticalAlignment="Top" Width="300">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Challenge">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock FontSize="16" Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>-->
</StackPanel>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
A GridView may not be the control that I finally settle on, but if I know how to bind it then I should be able to use that knowledge with another control.
Intellisense helps a lot in determining which properties are available, but Activities isn't one. I only get strings such as Name and Description which work correctly (first two TextBlock).
The only problem I see is that you are using the wrong DataType in the inner GridView. The type in Activities collection is Challenge.Activity, which is a nested class and nested classes are denoted by plus sign (+) in XAML, so data:Challenge+Activity:
<GridView DataContext="{Binding}" ItemsSource="{x:Bind Activities}" SelectionMode="None"
IsItemClickEnabled="False" IsSwipeEnabled="False" CanDragItems="False"
HorizontalAlignment="Left" Margin="0,70,0,0" VerticalAlignment="Top" Width="300">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Challenge+Activity">
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left">
<TextBlock FontSize="16" Text="{x:Bind Name}" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
VS may still throw some warnings but those will disappear after successful compilation.
Showing the categories is no problem, but I can't get it to show the objects that should be inside the categories. What am I doing wrong?
Thank you in advance.
XAML- Datatemplates.
<DataTemplate x:Key="Component">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
<HierarchicalDataTemplate x:Key="Category"
ItemTemplate="{StaticResource Component}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
XAML: Treeview
<telerik:RadTreeView x:Name="treeview" IsDragDropEnabled="True"
HorizontalAlignment="Left" Margin="10,10,0,10" Width="190"
IsManipulationEnabled="True"
IsExpandOnSingleClickEnabled="True"
ItemTemplate="{StaticResource Category}" />
C#: The categoryclass containing childobjects for the treeview.(Generated from databasemodel)
public partial class Category
{
public Category()
{
this.MethodComponent = new HashSet<MethodComponent>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<MethodComponent> MethodComponent { get; set; }
public override string ToString()
{
return Name;
}
}
}
C# Getting the data:
public List<Category> Get_Categories()
{
using (var context = new ProcessDatabaseEntities())
{
return context.Category.ToList();
}
}
C# binding the data:
treeview.ItemsSource = d.Get_Categories();
You need to set ItemsSource on HierarchicalDataTemplate to MethodComponent to populate parent node with child collection.
<HierarchicalDataTemplate x:Key="Category"
ItemTemplate="{StaticResource Component}"
ItemsSource="{Binding MethodComponent}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
I have a class with a list of images in it.
public class RSSClass
{
public string Title { get; set; }
public string Summary { get; set; }
public string PubDate { get; set; }
public List<ImageData> ImagePath { get; set; }
public class ImageData
{
public Uri ImageLocation
{
get;
set;
}
}
}
Hers the XAML
<ListBox Name="lstRSS">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
</StackPanel.Resources>
<TextBlock Text="{Binding Path=Title}"> </TextBlock>
<TextBlock Text="{Binding Path=PubDate}"></TextBlock>
<TextBlock Text="{Binding Path=Summary}"></TextBlock>
<ListBox x:Name="ImageListBox" ItemsSource="{Binding ImagePath}">
<DataTemplate>
<Image x:Name="image1" Source="{Binding}" MaxHeight="80" MaxWidth="120" Margin="0"></Image>
</DataTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The inner list box, ImageListBox, binds and shows the string value of the Uri. Im just not sure what to bind the image in the inner list box, image1, to?
Any help much appreciated.
Regards
Ross
You are missing <ListBox.ItemTemplate> around your <DataTemplate>. This confuses ListBox, so it thinks it is actualy an item, not a template.
Once you implement #Euphoric's resolution, bind the image1's source to ImageLocation. Example:
<Image x:Name="image1" Source="{Binding ImageLocation}" MaxHeight="80" MaxWidth="120" Margin="0"></Image>
This may be a very simple question, but at the moment I don't actually know what to google.
If I had an object like this:
public class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In my VM I have a list of employees (public List<Employee> Employees). It's easy to bind this in my Xaml to a ListBox:
<ListBox ItemsSource={Binding Employees}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But what if my list of employees would contain strings and not Employee objects? How could I bind these string values to the TextBlock in the data template?
Just write {Binding} where you specify the binding.
How do I get my class properties to show up in the ListBox?
XAML:
<ListBox x:Name="lstPlayers" >
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Player.FirstName}"></TextBlock>
<TextBlock Text="{Binding Player.LastName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox>
C#:
public class Player
{
string FirstName { get; set; }
string LastName { get; set; }
}
public void LoadPlayers()
{
foreach (Player player in Players)
{
lstPlayers.Items.Add(player);
}
}
The only thing that shows up in the ListBox is
TestApplication1.Player
You have some problems with you current implementation. First, the DataTemplate should be placed inside the ItemTemplate for the ListBox. Second, the DataContext for each ListBoxItem will be an instance of Player so you should bind directly to FirstName and LastName. Third, the properties in Player should be made public for the DataBinding to work.
<ListBox x:Name="lstPlayers" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"></TextBlock>
<TextBlock Text="{Binding LastName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public class Player
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Also, instead of adding the collection item by item to the ListBox, just set it as ItemsSource
lstPlayers.ItemsSource = Players;
DataTemplate should be inside ListBox.ItemTemplate.
set the collection, Players as ItemSource
and
<ListBox x:Name="lstPlayers" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"></TextBlock>
<TextBlock Text="{Binding LastName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
you have to add the DataType to your DataTemplate.
<DataTemplate DataType="{x:Type local:Player}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"></TextBlock>
<TextBlock Text="{Binding LastName}"></TextBlock>
</StackPanel>
</DataTemplate>
local is the namespace for your TestApplication1.Player. you can set the datatemplate to the listebox.itemtemplate or as a resource of any "parent object"