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>
Related
Basically, when a user clicks a button I would like to add a list of the names of the currently running applications with their icon next to them within a ComboBox. I know how to get my list of applications and my icons but am unsure how to link everything together. My XAML for the ComboBox currently looks like the following:
<ComboBox x:Name="dial1AppSelection" Grid.Column="3" Grid.Row="4" MinHeight="25" Height ="25" MaxHeight="35" MinWidth="120" Margin="4,0,0,0" SelectionChanged="dial1AppSelection_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="20" Source="???" />
<TextBlock ><Run Text="???" /></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Add to your combobox
ItemsSource="{Binding YourCollection}"
Create class for your objects:
public class MyProcess
{
public ImageSource Image { get; set; }
public string Text { get; set; }
}
Add such code to your MainWindow.xaml.cs
public ObservableCollection<MyProcess> YourCollection { get; set; }
public MainWindow()
{
InitializeComponent();
YourCollection = new ObservableCollection<MyProcess>();
YourCollection.Add(new MyProcess() { Image ="image1", Text = "txt1"});
DataContext = this;
}
Insert fields names to your xaml code:
Source="{Binding Path=Image}"
Text="{Binding Path=Text}"
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.
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
In a project for windows phone 8 , i have a List<> of objects of this type.
public class Media
{
public string idNews { get; set; }
public string video_url { get; set; }
public string idMenu { get; set; }
public string image { get; set; }
public string video_image { get; set; }
public string url { get; set; }
}
i then bind that list to a XAML
MediaScroll.DataContext = media.listaMedia;
and in my XAML i have
<ScrollViewer Name="MediaScroll" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" Background="{x:Null}" VerticalAlignment="Top" >
<ItemsControl Name="ItControl" ItemTemplate="{StaticResource ItemTemplate2}" ItemsPanel="{StaticResource ItemsPanelTemplate1}" ItemsSource="{Binding}" />
</ScrollViewer>
and
<ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="ItemTemplate2">
<StackPanel Width="480">
<Image Name="overlay" Source="/Assets/play#2x.png" Width="75" Canvas.ZIndex="10" Margin="203,85,202,0" />
<Image Tag="{Binding id}" Source="{Binding image}" Stretch="Fill" VerticalAlignment="Top" Margin="0,-160,0,0" Tap="Image_Tap" />
</StackPanel>
</DataTemplate>
my question is , how can i bind either image or video_image depending on witch on ins't empty, also , how can i make " Image Name="overlay" " only display if the other image is bound with a video_image
Inside your StackPanel, create only one Image control that has the Source set up with a Binding image.
Create a Converter and attach that to your Binding to programatically return either your play#2x.png as an ImageSource or your image.
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"