Filling ListBox with custom control in windows phone - c#

I am working on windows phone app where I need to get the latest streams from a site. I currently made a custom control that can hold each item from JSON:
<UserControl x:Class="TwitchStationApp.StreamItem"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="195" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Height="195" Width="469">
<Image Height="156" HorizontalAlignment="Left" Margin="12,12,0,0" Name="imageChannel" Stretch="Fill" VerticalAlignment="Top" Width="156" />
<TextBlock Height="84" HorizontalAlignment="Left" Margin="174,48,0,0" Name="textBlockStatus" Text="TextBlock" VerticalAlignment="Top" Width="294" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,12,0,0" Name="textBlockChanelName" Text="TextBlock" VerticalAlignment="Top" Width="294" Foreground="#FFB0CB3E" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,138,0,0" Name="textBlockViewers" Text="TextBlock" VerticalAlignment="Top" Width="294" />
</Grid>
</UserControl>
So I will make a list of items List<Stream> _stream = new ..... So this list will be populated by lets say 10 items. For each item I need to make a User control (above) and add it to the ListBox so that users can scroll and select (click/tap) on the item they want to get more information about.
What is the best way to do this? I checked microsoft website and there is something about having ItemTemplate in a XAML file in <Window.Resource> tag but I dont know where and how to create this file and link it to the listbox I have.

This is typically done using a data template.
Assuming you have a collection of StreamTypes
public class StreamType
{
public string Title { get; set; }
public string Description { get; set; }
}
You can define a Data template in
Application wide – in app.xaml
Page Scope – on the page
Control container scope – local to the container of the listbox
Within the Listbox itself
To define it page wide:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="SharedStreamTemplate">
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
In your list box, assign the data template to the item template
<ListBox x:Name="lstStreams" ItemTemplate="{StaticResource SharedStreamTemplate}" />
If there isn't a plausible cause for you to re-use the template, just assign it directly in the listbox
<ListBox x:Name="lstStreams">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Update
In your code behind
// Constructor
public MainPage()
{
InitializeComponent();
BindStreams();
}
private void BindStreams()
{
lstStreams.ItemsSource = new List<StreamType>
{
new StreamType { Description = "Description One", Title = "Title One"},
new StreamType { Description = "Description Two", Title = "Title Two"},
new StreamType { Description = "Description Three", Title = "Title Three"},
};
}

That's right you need to use the ItemsControl.ItemTemplate property. Using this property, you can specify a template that will be applied to each item in the list. Here's sample code:
Model:
public class Model
{
public string Name { get; set; }
public Guid Id { get; set; }
}
XAML
<ListBox ItemsSource="{Binding Path=MyItemsSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Id}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

C# wpf caliburn.Micro MahApps HamburgerMenu.ContentTemplate data binding is not working

I'm making an application using Caliburn.Micro(for easy data binding and stuff) and MahApps.Metro(for designing).
I've created a View name 'MainView' which has HamburgerMenu of MahApps.
My issue is data binding is working fine under HamburgerMenu.ContentTemplate tag
Here is my HamburgerMenu.ContentTemplate xaml.
<Page x:Class="Sample.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:utils="clr-namespace:Omni.WindowsClient.Utils"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Omni.WindowsClient.Views"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="600">
<Page.Resources>
<DataTemplate x:Key="HamburgerMenuItem"
DataType="{x:Type mah:HamburgerMenuItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Margin="12"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{Binding Glyph}"
Stretch="UniformToFill" />
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<mah:HamburgerMenu x:Name="HamburgerMenuControl"
SelectedIndex="0"
ItemTemplate="{StaticResource HamburgerMenuItem}"
OptionsItemTemplate="{StaticResource HamburgerMenuItem}"
IsPaneOpen="True"
DisplayMode="CompactInline"
cal:Message.Attach="[Event ItemClick] = [Action ShowDetails(HamburgerMenuControl.SelectedItem)]"
DataContext="{Binding RelativeSource={RelativeSource self}}">
<mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenuItemCollection>
<mah:HamburgerMenuItem Label="System Status">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Tasks" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem Label="Inbox">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Inbox" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Certificate" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
</mah:HamburgerMenuItemCollection>
</mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenu.ContentTemplate>
<DataTemplate DataType="{x:Type mah:HamburgerMenuItem}">
<Grid utils:GridUtils.RowDefinitions="48,*">
<!--cal:Action.TargetWithoutContext="{Binding ElementName=HamburgerMenuControl, Path=DataContext}"-->
<Border Grid.Row="0"
Background="{DynamicResource MahApps.Metro.HamburgerMenu.PaneBackgroundBrush}">
<TextBlock x:Name="Header"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Foreground="White" />
<!--Text="{Binding Path=Header, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"-->
</Border>
<Frame Grid.Row="1"
cal:Message.Attach="RegisterFrame($source)"
DataContext="{x:Null}"
NavigationUIVisibility="Hidden" />
</Grid>
</DataTemplate>
</mah:HamburgerMenu.ContentTemplate>
</mah:HamburgerMenu>
</Grid>
</Page>
and respective view model code is:
using Caliburn.Micro;
using MahApps.Metro.Controls;
using System.Windows.Controls;
namespace Sample.ViewModels
{
public class MainViewModel : Screen
{
private readonly SimpleContainer _container;
private INavigationService _navigationService;
private string _header;
public string HeaderTitle
{
get { return _header; }
set
{
_header = value;
NotifyOfPropertyChange();
}
}
public MainViewModel(SimpleContainer container)
{
this._container = container;
DisplayName = "Main";
}
public void RegisterFrame(Frame frame)
{
_navigationService = new FrameAdapter(frame);
_container.Instance(_navigationService);
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
}
public void ShowDetails(HamburgerMenuItem menuItem)
{
switch (menuItem.Label)
{
case "System Status":
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
break;
case "Inbox":
_navigationService.NavigateToViewModel(typeof(InboxViewModel));
HeaderTitle = "Inbox";
break;
default:
break;
}
}
}
}
I want to change View in frame under HamburgerMenu.ContentTemplate when I click on menu item.
Like System Status view is SystemStatusView
and Inbox view is InboxView.
My code is working fine (it changes the view in frame and change the Header label too) if I don't use HamburgerMenu.ContentTemplate. But I want to use HamburgerMenu.ContentTemplate to work with HamburgerMenu.
Thanks!
If it's working fine if you don't use HamburgerMenu.ContentTemplate, but stops working when you do, the problem is probably with you overwriting the default template in a way that doesn't support all functionalities of a control.
I'd suggest you to use Blend to get the default HamburgerMenu.ContentTemplate, then just edit it to your needs, without changing too much (keep in mind that names of controls used as a template may have a crucial meaning, so be careful what you are editing).
If you don't know how to use Blend to get your control's template, here is a simple tutorial described in a documentation of Telerik controls (don't worry, it works the same for all controls). You just need to create copy of a HamburgerMenu.ContentTemplate, paste it to your application and you are good to go (editing).

ListBox Item layout in XAML/WPF

I am struggling last days to achieve following layout:
I have a ListBox with template for each Item:
Label always anchored on left side
Label always anchored on right side
Label (TextBlock) in middle with flexible size
3rd label bellow, so far this is easiest to set :)
Main problem in my example is that I can't made middle text (that can be long) to adjust, but not push suffix (red) label while I am resizing ListBox.
I hope that this layout is possible, and that I am missing something trivial.
What's interesting is that 1st example (bellow) work well "outside" listbox. Do I need somehow force realign of listbox while resizing?
Thanks for any help.
I have attached bellow 2 examples I tried (beside many other):
XAML:
<Window x:Class="WPF_Experiments.MainWindow"
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="clr-namespace:WPF_Experiments"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="400">
<Window.Resources>
<DataTemplate x:Key="Template1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Foreground="Blue" Background="Aqua" Content="{Binding Prefix}" />
<Label Grid.Column="1" Content="{Binding Description}" />
<Label Grid.Column="2" Foreground="Magenta" Background="Beige" Content="{Binding Suffix}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="Template2">
<DockPanel LastChildFill="True">
<Label Grid.Column="0" Foreground="Blue" Background="Aqua" Content="{Binding Prefix}" />
<Label Grid.Column="2" DockPanel.Dock="Right" Foreground="Magenta" Background="Beige" Content="{Binding Suffix}" />
<TextBlock Grid.Column="1" Text="{Binding Description}" TextTrimming="CharacterEllipsis" />
</DockPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ListBox Name="MyListBox"
ItemTemplate="{DynamicResource Template2}"/>
</StackPanel>
</Window>
C#:
namespace WPF_Experiments
{
class Item
{
public string Prefix { get; set; }
public string Description { get; set; }
public string Suffix { get; set; }
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Item> items = new List<Item>();
items.Add(new Item() { Prefix = "001", Description = "Item 0", Suffix = "cm" });
items.Add(new Item() { Prefix = "002", Description = "This is very long item that maybe will not fit", Suffix = "in" });
items.Add(new Item() { Prefix = "003", Description = "Item 2", Suffix = "m" });
MyListBox.ItemsSource = items;
}
}
}
(Edit) One more try with StackPanel:
<DataTemplate x:Key="Template3">
<StackPanel Orientation="Horizontal">
<Label Foreground="Blue" Background="Aqua" Content="{Binding Prefix}" />
<TextBlock Text="{Binding Description}" TextTrimming="CharacterEllipsis" />
<Label Foreground="Magenta" Background="Beige" Content="{Binding Suffix}" HorizontalAlignment="Right" />
</StackPanel>
</DataTemplate>
You can achieve this by disabling horizontal scrolling for ListBox:
<ListBox Name="MyListBox" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemTemplate="{DynamicResource Template2}"/>

Binding data in Hub Control in Windows universal apps with list items

Hello I have list defined as follows
public class Article
{
public string title { get; set; }
public string author { get; set; }
public string content { get; set; }
}
public static List<Article> articles = new List<Article>();
I use a async method to get xml data from server and parse it.
private async void Button_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
//Progress Bar
prg.Visibility = Visibility.Visible;
string xml = string.Empty;
Uri url = new Uri("http://someurl.com/someting.php");
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "text/html,application/xhtml+xml,application/xml");
var response = await httpClient.GetAsync(url);
using (var responseStream = await response.Content.ReadAsStreamAsync())
using (var streamReader = new StreamReader(responseStream))
{
xml = streamReader.ReadToEnd();
}
try
{
Debug.WriteLine("Parsing to start");
string eve = "article";
XDocument loadedData = XDocument.Parse(xml);
foreach (var item in loadedData.Descendants(eve))
{
try
{
Article c = new Article();
c.title = item.Element("title").Value;
c.author = item.Element("author").Value;
c.content = item.Element("content").Value;
articles.Add(c);
}
catch
{
Debug.WriteLine("Failed");
}
}
Debug.WriteLine("About to add items");
articlelist.DataContext = articles;
Debug.WriteLine("Items added");
}
catch
{
Debug.WriteLine("Parsing Failed");
}
prg.Visibility = Visibility.Collapsed;
}
Below is the xaml UI elments
<Page
x:Class="Airtrixz.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Airtrixz"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ProgressBar Grid.Row="0" IsIndeterminate="True" Foreground="{StaticResource PhoneAccentBrush}" VerticalAlignment="Top" Height="16" x:Name="prg" Visibility="Collapsed"/>
<TextBlock Text="Airtrixz" Margin="10,0,0,0" FontSize="30"/>
<Hub Margin="0,50" Foreground="White">
<HubSection Header="posts" x:Name="articlelist" >
<DataTemplate>
<StackPanel Background="Transparent">
<TextBlock Foreground="White" Text="{Binding title}" Height="25" />
<TextBlock Foreground="White" Text="{Binding author}" Height="25"/>
<TextBlock Foreground="White" Text="{Binding content}" Height="25"/>
</StackPanel>
</DataTemplate>
</HubSection>
</Hub>
<Button Width="100" Margin="10,10,0,0" VerticalAlignment="Bottom" Height="50" Tapped="Button_Tapped" Content="Load"/>
</Grid>
</Page>
Doing articlelist.DataContext=articles seems to be fine. But no list items are being displayed and it gives the following error for title, content and author properties in HubSection
Error: BindingExpression path error: 'title' property not found on 'System.Collections.Generic.List1[[Airtrixz.MainPage+Article, Airtirxz.WindowsPhone, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. BindingExpression: Path='title' DataItem='System.Collections.Generic.List1[[Airtrixz.MainPage+Article, Airtirxz.WindowsPhone, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'; target element is 'Windows.UI.Xaml.Controls.TextBlock' (Name='null'); target property is 'Text' (type 'String')
Could anyone give me a solution for this?
Since your HubSection's DataTemplate is a StackPanel, it will only display a single object, not an entire list of articles. For that you need a ListBox or a ListView. This is why you are getting the Bindings error; it is trying to find the 'title' property on your List, which of course is not there. Try this:
<Hub Margin="0,50" Foreground="White">
<HubSection Header="posts" x:Name="articlelist" >
<DataTemplate>
<ListView ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Background="Transparent">
<TextBlock Foreground="White" Text="{Binding title}" Height="25" />
<TextBlock Foreground="White" Text="{Binding author}" Height="25"/>
<TextBlock Foreground="White" Text="{Binding content}" Height="25"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</HubSection>
</Hub>
This will bind the ItemsSource of the ListView to the DataContext of the HubSection, which you are setting to articles in your Button_Tapped callback, so it should all work. post a reply either way, and I can try to help debug more.
Not sure if I should put it here as an answer as I've never used Hub control but my guess would be that HubSections will have to be populate like this:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<HubSection Header="posts">
<DataTemplate>
<StackPanel Background="Transparent">
<TextBlock Foreground="White" Text="{Binding title}" Height="25" />
<TextBlock Foreground="White" Text="{Binding author}" Height="25"/>
<TextBlock Foreground="White" Text="{Binding content}" Height="25"/>
</StackPanel>
</DataTemplate>
</HubSection>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

List picker not showing items.

I have a list picker when clicking on the control to select another item it seems to look like it is going to work but is all white I can sometimes get it to select another item but cant see what is selected until you are off of it. This is how I have it set up. When I set it to full mode the name space is the only thing that shows not the actual name of the item. All I am trying to do is upon loading the view I need to load the listPicker with values.
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Name="PickerItemTemplate" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding TankTypeName}" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="PickerFullModeItemTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding TankTypeName}" Style="{StaticResource PhoneTextNormalStyle}" FontFamily="{StaticResource PhoneFontFamilyLight}"/>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBox Height="72" HorizontalAlignment="Left" Margin="0,50,0,0" Name="TextBoxProjectName" Text="" VerticalAlignment="Top" Width="456" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="12,28,0,0" Name="TextBlockProjectName" Text="Tank Name:" VerticalAlignment="Top" />
<toolkit:ListPicker Header="Tank Type:" ItemsSource="{Binding TankTypes}"
ItemTemplate="{StaticResource PickerItemTemplate}"
FullModeItemTemplate="{Binding PickerFullModeItemTemplate}"
SelectedItems="{Binding SelectedTankTypes,Mode=TwoWay}"
Height="100" HorizontalAlignment="Left"
Margin="6,144,0,0" Name="ListPickerTankType"
VerticalAlignment="Top" Width="444" >
</toolkit:ListPicker>
</Grid>
View Model
private List<TankType> _tankType;
private ObservableCollection<Object> _selectedTankType= new ObservableCollection<object>();
/// <summary>
/// Collection of Tank Type objects.
/// </summary>
public List<TankType> TankTypes
{
get
{
return _tankType;
}
set
{
if (value != _tankType)
{
_tankType = value;
NotifyPropertyChanged("TankType");
}
}
}
public ObservableCollection<object> SelectedTankTypes
{
get
{
return _selectedTankType;
}
set
{
if (_selectedTankType == value)
{
return;
}
_selectedTankType = value;
NotifyPropertyChanged("SelectedTankTypes");
}
}
This is a edit page so in the constructor of the view.
public TaskDetail()
{
InitializeComponent();
var tankTypeViewModel = new ViewModels.TankVewModel();
tankTypeViewModel.GetTankTypes();
ListPickerTankType.DataContext = tankTypeViewModel;
}
Revised OK I removed the height on the listpicker and now can see it made it bigger so the three items are there. I just cant seem to change the font color to black so I can see it when you click on the listpicker.
Figured it out. I needed to remove the height and set the foreground color to black.

How to bind data correctly to a WPF button using MVVM

Here is my setup, it seems I am not binding the data correctly. The outcome should be a Button with an Image and text displayed. Nothing is displayed.
<UserControl x:Class="AmebaPrototype.UI.LandingPivot.featureControl"
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"
mc:Ignorable="d"
d:DesignHeight="330" d:DesignWidth="960"
DataContext="{Binding Source={StaticResource viewModelLocator}, Path=VideoViewModel}"
>
<UserControl.Resources >
<DataTemplate x:Key="custTemplate" >
<StackPanel >
<Image Source="{Binding ImagePath}"/>
<TextBlock Text="{Binding MyTitle}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="{x:Null}" >
<Button Content="Button" Height="316"
HorizontalAlignment="Left" Margin="12,2,0,0"
Name="button1" VerticalAlignment="Top"
Width="423" Click="button1_Click"
ContentTemplate="{DynamicResource custTemplate}"
/>
<Button Content="Button" Height="156" HorizontalAlignment="Left" Margin="441,2,0,0" Name="button2" VerticalAlignment="Top" Width="208" Click="button2_Click" />
<Button Content="Button" Height="156" HorizontalAlignment="Left" Margin="669,2,0,0" Name="button3" VerticalAlignment="Top" Width="208" />
<Button Content="Button" Height="156" HorizontalAlignment="Left" Margin="441,162,0,0" Name="button4" VerticalAlignment="Top" Width="208" />
<Button Content="Button" Height="156" HorizontalAlignment="Left" Margin="669,162,0,0" Name="button5" VerticalAlignment="Top" Width="208" />
</Grid>
Model:
public class Video
{
public string MyTitle { get; set; }
public string ImagePath { get; set; }
}
ViewModel
public ViewModel VideoViewModel
{
get
{
if(viewmodel == null)
{
viewmodel = new ViewModel();
viewmodel.ListData.Clear();
viewmodel.ListData.Add(new Video { MyTitle = "Title1", ImagePath = "exampleimage.com/image.png" });
viewmodel.ListData.Add(new Video { MyTitle = "Title2", ImagePath = "exampleimage.com/image.png" });
}
return viewmodel;
}
}
If you really want to do this using a DataTemplate, then:
<Button>
<Button.Content>
<x:Type TypeName="Visual"/>
</Button.Content>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<ContentPresenter ContentSource="Content"/>
</Grid>
</ControlTemplate>
</Button.Template>
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"/>
</DataTemplate>
</Button.ContentTemplate>
</Button>
Your ViewModel binding should be okay to use here so in the DataTemplate you can just tweak it to include your Image and TextBlock.
DataTemplate in resources:
<DataTemplate x:Key="bTemplate">
<Button Label="{Binding MyTitle}"
Command="{Binding Execute}">
<Image Source="{Binding ImagePath}" />
</Button>
</DataTemplate>
Not exactly as in your question but then you can use a control that takes an ItemSource such as a ListView:
<ListView
ItemsSource="{Binding ListData}"
ItemTemplate="{StaticResource bTemplate}"
>
</ListView>
I added a Command , since it is necessary if you want to implement MVVM rather than event click.

Categories