ICommand does not fire with button in ItemTemplate - mvvm-light

I am currently doing a test with ICommand and I wonder why ICommand does not fire with button in ListBox.ItemTemplate. But when used outside the template, it works.
here's the window xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1" x:Class="WpfApplication1.Window2"
Title="Window2" Height="300" Width="300">
<Window.DataContext>
<local:W2VM/>
</Window.DataContext>
<Grid>
<ListBox x:Name="listHistory" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemsSource="{Binding History}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding ''}" />
<Button
Grid.Column="1"
HorizontalAlignment="Right"
x:Uid="btnDeleteHistoryItem"
x:Name="btnDeleteHistoryItem"
Content="r"
FontFamily="Marlett"
Visibility="Hidden" Command="{Binding MeClick}"
/>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" TargetName="btnDeleteHistoryItem" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content=" exit " VerticalAlignment="Bottom" Command="{Binding ExitCommand}" />
</Grid>
</Window>
here's the complete ViewModel code
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
}
}
public class W2VM : ViewModelBase
{
public List<string> _History = new List<string>();
public List<string> History
{
get { return this._History; }
}
public ICommand MeClick
{
get;
internal set;
}
public ICommand ExitCommand
{
get;
internal set;
}
public W2VM()
{
this.History.AddRange(new string[] {
"jayson", "hello", "world"
});
this.MeClick = new RelayCommand(Test);
this.ExitCommand = new RelayCommand(Exit);
}
void Exit()
{
Application.Current.Shutdown();
}
void Test()
{
Debug.WriteLine("hello world");
MessageBox.Show("do something incredible");
}
}
}
Test() does not fire
ok I got it working..
<Window.Resources>
<me:W2VM x:Key="local" />
</Window.Resources>
instead of
<Window.DataContext>
<local:W2VM/>
</Window.DataContext>
and my window grid
<Grid DataContext="{StaticResource local}">
<ListBox x:Name="listHistory" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemsSource="{Binding History}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding ''}" />
<Button
Grid.Column="1"
HorizontalAlignment="Right"
x:Uid="btnDeleteHistoryItem"
x:Name="btnDeleteHistoryItem"
Content="r"
FontFamily="Marlett"
Visibility="Hidden" Command="{Binding MeClick, Source={StaticResource local}}" />
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Visibility" TargetName="btnDeleteHistoryItem" Value="Visible" />
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content=" exit " VerticalAlignment="Bottom" Command="{Binding ExitCommand}" />
</Grid>
now this will raise another question.
How would I know which ListViewItem was clicked when the btnDeleteHistoryItem command was just routed?

Are you using the relaycommand of mvvm-light?
I use command parameters to pass information to the command method:
<Button
Grid.Column="1"
HorizontalAlignment="Right"
x:Uid="btnDeleteHistoryItem"
x:Name="btnDeleteHistoryItem"
Content="r"
FontFamily="Marlett"
Visibility="Hidden" Command="{Binding MeClick, Source=StaticResource local}}"
CommandParameter="YourUniqueIdentifyingVariable" />
and then in your view model:
public RelayCommand<string> MeClick{
get { return _MyClick; }
private set { _MyClick = value; }
}
public New()
{
MeClick = new RelayCommand<string>(MySub, MySubIsEnabled);
}
private void MySub(string sParam)
{
//do stuff here, YourUniqueIdentifyingVariable is sParam
}
private bool MySubIsEnabled(string sParam)
{
return true;
}
you can bind "YourUniqueIdentifyingVariable" to the ID of the record or some other value that you can process in your command method
Code is untested but should work

Related

Binding StackLayout to ViewModel doens't work

I would like to have a property in my ViewModel that is linked to my StackLayout. I tried this by Binding my StackLyout to the ViewModel.
When I click on a button, this layout should be made invisible.
When I do this with the code below, my program crashes with a NulReferenceObject: Object Reference not set to an instance of an object. The StackLayout that i am talking about is the first one in the code below.
<FlexLayout>
<StackLayout BindableLayout.ItemTemplate="{Binding CreateQuizPageQuizNameSL}"> // This StackLayout should be bind to the ViewModel
<Label Text="Create New Quiz" />
<StackLayout >
<Entry Text="{Binding QuizNameInput}" Placeholder="Enter quiz name"/>
</StackLayout>
</StackLayout>
<Button Command="{Binding SubmitCreateQuizCommand}" Text="Create my quiz now!"></Button>
</FlexLayout>
ViewModel
internal class CreateQuizPageViewModel
{
// Quiz Name Input
public String QuizNameInput { get; set; }
// Command submit creating a quiz
public Command SubmitCreateQuizCommand { get; set; }
public StackLayout CreateQuizPageQuizNameSL { get; set; } = new StackLayout();
public CreateQuizPageViewModel()
{
// Declaring a new command, giving the OnSubmitCreateNewQuizClick to the delegate
SubmitCreateQuizCommand = new Command(OnSubmitCreateNewQuizClick);
}
// When a user submit the creation of new quiz
public void OnSubmitCreateNewQuizClick()
{
CreateQuizPageQuizNameSL.IsVisible = false;
}
}
Here is how to switch two layouts using IsVisible binding.
FIRST Add Nuget Xamarin.CommunityToolkit to your Xamarin Forms project. (The one that is "MyProjectName", without ".iOS" or ".Android" at end.)
TwoLayoutPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:local="clr-namespace:TestBugs"
x:Class="TestBugs.TwoLayoutPage">
<ContentPage.BindingContext>
<local:TwoLayoutViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<xct:InvertedBoolConverter x:Key="InvertedBoolConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<StackLayout
IsVisible="{Binding UseSecondLayout, Converter={StaticResource InvertedBoolConverter}}"
VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label Text="First Layout" FontSize="20" />
<Button Text="To Second" Command="{Binding SwitchToSecondLayoutCommand}" />
</StackLayout>
<StackLayout IsVisible="{Binding UseSecondLayout}"
VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label Text="Second Layout!" FontSize="32" />
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
TwoLayoutViewModel.cs:
using Xamarin.Forms;
namespace TestBugs
{
public class TwoLayoutViewModel : BindableObject
{
private bool _usesecondLayout = false;
public bool UseSecondLayout {
get => _usesecondLayout;
set {
_usesecondLayout = value;
OnPropertyChanged();
}
}
public TwoLayoutViewModel()
{
SwitchToSecondLayoutCommand = new Command(SwitchToSecondLayout);
}
public Command SwitchToSecondLayoutCommand { get; set; }
private void SwitchToSecondLayout()
{
UseSecondLayout = true;
}
}
}

Xamarin.Forms Why is my tap command not working?

I have this kind of tap command in my carousel view:
<Image
x:Name="img_adPic"
HeightRequest="150"
Aspect="AspectFill"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Source="{Binding thumbnail}">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference page}}" CommandParameter="{Binding Path=BindingContext.CurrentIndex, Source={x:Reference page}}"/>
</Image.GestureRecognizers>
</Image>
I gave my contentpage a name :
<ContentPage x:Name="page" >
Now in my class:
public ICommand CarouselItemTapped{ get; set; }
public Page_MainMenuDetail()
{
InitializeComponent();
CarouselItemTapped = new Xamarin.Forms.Command((selectItem) =>
{
});
instance = this;
}
But no matter what I try, the command is NEVER fired. I think i did everything as in the tutorials, why is this not working?
Thank you
You could refer to the code below about how to use the TapCommand. The command would be triggled when you tap on the image.
Xaml:
<ContentPage.Content>
<AbsoluteLayout>
<CarouselView
x:Name="carouselView"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
IndicatorView="indicatorview">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image
x:Name="img_adPic"
Aspect="AspectFill"
HeightRequest="150"
HorizontalOptions="FillAndExpand"
Source="{Binding .}"
VerticalOptions="FillAndExpand">
<Image.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Path=BindingContext.TapCommand, Source={x:Reference page}}" />
</Image.GestureRecognizers>
</Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView
x:Name="indicatorview"
AbsoluteLayout.LayoutBounds=" 0.5,0.95,100,100"
AbsoluteLayout.LayoutFlags=" PositionProportional"
IndicatorColor=" LightGray"
IndicatorSize=" 10"
SelectedIndicatorColor=" Black" />
</AbsoluteLayout>
</ContentPage.Content>
Code behind:
public partial class Page2 : ContentPage
{
public ICommand CarouselItemTapped { get; set; }
public ICommand TapCommand { get; set; }
public Page2()
{
InitializeComponent();
var list = new List<string>
{
"pink.jpg",
"pink.jpg",
"pink.jpg",
"pink.jpg",
"pink.jpg",
};
carouselView.ItemsSource = list;
//CarouselItemTapped = new Xamarin.Forms.Command((selectItem) =>
//{
//});
//instance = this;
TapCommand = new Command(commandEvent);
this.BindingContext = this;
}
public void commandEvent()
{
}
}

Xamarin Forms TemplateBinding to Command In BasePage

I have a BasePage created using ControlTemplates that contains a loading overlay for each child to use - This overlay has a "cancel" button on it, but for some reason I can't get ICommands to execute when I tap the buttons. Clicked events work fine but I'd like to understand what the problem is with Commands.
I researched the issue and found I should be binding using Command="{TemplateBinding MyCommand}" since my content is within a ControlTemplate but still no luck, however I am also binding the Text property and this is working fine, so I'm a bit confused.
Here's a cut down version of what I've hacked together.
Here's my BasePage XAML with the button in question:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage x:Name="this" NavigationPage.HasNavigationBar="False" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:helpers="clr-namespace:ShoppingListNEW.MarkupExtensions" xmlns:views="clr-namespace:ShoppingListNEW.Views" x:Class="ShoppingListNEW.Pages.BasePage">
<ContentPage.ControlTemplate>
<ControlTemplate>
<Grid Padding="0" RowSpacing="0" ColumnSpacing="0">
<StackLayout>
<StackLayout.Padding>
<OnPlatform x:TypeArguments="Thickness" iOS="0,30,0,0"/>
</StackLayout.Padding>
<ScrollView VerticalOptions="FillAndExpand" >
<StackLayout RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}" Orientation="Vertical">
<ContentPresenter />
</StackLayout>
</ScrollView>
</StackLayout>
<AbsoluteLayout IsVisible="False" Grid.Row="0" Grid.Column="0" x:Name="loading" BackgroundColor="#85000000" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<ActivityIndicator Color="Lime" Scale="2" IsRunning="true" IsEnabled="true" IsVisible="true" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5,0.4" />
<Button IsVisible="True" Text="{TemplateBinding MyTextLabel}" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5,0.5" Command="{TemplateBinding MyCommand}" />
</AbsoluteLayout>
</Grid>
</ControlTemplate>
</ContentPage.ControlTemplate>
</ContentPage>
And here's the C# for that BasePage:
using System;
using System.Windows.Input;
using ShoppingListNEW.Views;
using Xamarin.Forms;
namespace ShoppingListNEW.Pages
{
public partial class BasePage : ContentPage
{
public string MyTextLabel { get; set; } = "This Works";
public ICommand MyCommand { get; set; }
public BasePage()
{
InitializeComponent();
MyCommand = new Command(() =>
{
Console.Write("But this doesn't work :(");
});
}
public void ShowHideLoading(bool showhide, bool allowCancel = false)
{
var loadingLayout = (AbsoluteLayout)GetTemplateChild("loading");
var cancelButton = loadingLayout.FindByName<Button>("btnCancel");
cancelButton.IsVisible = allowCancel;
loadingLayout.IsVisible = showhide;
}
}
}
Any ideas?
On your ControlTemplate binding, please use the following code:
<Button
AbsoluteLayout.LayoutBounds="0.5,0.5"
AbsoluteLayout.LayoutFlags="PositionProportional"
Command="{TemplateBinding BindingContext.MyCommand}"
IsVisible="True"
Text="{TemplateBinding BindingContext.MyTextLabel}" />
I use your code to create simple that you can take a look, please don't set AbsoluteLayout IsVisible="False".
<ContentPage.ControlTemplate>
<ControlTemplate>
<Grid Padding="0">
<StackLayout>
<ScrollView VerticalOptions="FillAndExpand">
<StackLayout
Orientation="Vertical"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Width}">
<ContentPresenter />
</StackLayout>
</ScrollView>
</StackLayout>
<AbsoluteLayout
x:Name="loading"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="#85000000">
<ActivityIndicator
AbsoluteLayout.LayoutBounds="0.5,0.4"
AbsoluteLayout.LayoutFlags="PositionProportional"
IsEnabled="true"
IsRunning="true"
IsVisible="true"
Scale="2"
Color="Lime" />
<Button
AbsoluteLayout.LayoutBounds="0.5,0.5"
AbsoluteLayout.LayoutFlags="PositionProportional"
Command="{TemplateBinding BindingContext.MyCommand}"
IsVisible="True"
Text="{TemplateBinding BindingContext.MyTextLabel}" />
</AbsoluteLayout>
</Grid>
</ControlTemplate>
</ContentPage.ControlTemplate>
public partial class Page19 : ContentPage
{
public Page19()
{
InitializeComponent();
this.BindingContext = new Viewmodel1();
}
}
public class Viewmodel1:ViewModelBase
{
private string _MyTextLabel;
public string MyTextLabel
{
get { return _MyTextLabel; }
set
{
_MyTextLabel = value;
RaisePropertyChanged("MyTextLabel");
}
}
public RelayCommand MyCommand { get; set; }
public Viewmodel1()
{
MyCommand = new RelayCommand(method);
MyTextLabel = "this is test";
}
private void method()
{
Console.WriteLine("this is test!");
}
}
Problem solved. Thanks to Mikolaj Kieres for the answer, it was a simple case of initialising the Command earlier so I moved it up above the InitializeComponent and that kicked it into life. Thanks!

Adding items to list using data binding in windows phone 8

I am trying to add list to the items dynamically as a part of learning Data Binding. But the items are not getting added. The app is so simple to just add a string to the list.
The XAML Code is as follows
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ListBox x:Name="TotalItems" Grid.Row="0" ItemsSource="{Binding Items_OC}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Width="440">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Item : " VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top" Margin="1,0,0,0" FontSize="{StaticResource PhoneFontSizeLarge}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<TextBox x:Name="NewItem" Grid.Column="0" TextWrapping="Wrap" Width="359"/>
<Button x:Name="Add" Grid.Column="1" Content="Add"/>
</Grid>
</Grid>`
The XAML.CS code is as follows
public ObservableCollection<Items> items_OC;
public ObservableCollection<Items> Items_OC
{
get
{
return items_OC;
}
set
{
if (items_OC != value)
{
MessageBox.Show("Item to added to collection");
items_OC = value;
NotifyPropertyChanged("Items_OC");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Items : INotifyPropertyChanged, INotifyPropertyChanging
{
string name;
public string Name
{
get
{
return name;
}
set
{
if (name != value)
{
NotifyPropertyChanging("Name");
name = value;
NotifyPropertyChanged("Name");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangingEventHandler PropertyChanging;
private void NotifyPropertyChanging(string propertyName)
{
if (PropertyChanging != null)
{
PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
}
}
}
private void Add_Click(object sender, RoutedEventArgs e)
{
Items it = new Items { Name = NewItem.Text };
Items_OC.Add(it);
}
Thanks for the help..
What your code seems missing is setting DataContext. Generally, binding resolves path from DataContext property. When you bind ItemsSource property this way :
<ListBox x:Name="TotalItems" Grid.Row="0" ItemsSource="{Binding Items_OC}" ...>
application will search Items_OC property of ListBox's DataContext. Currently, it won't find the property because DataContext is null. You can set DataContext to xaml.cs file from C# code like this :
this.DataContext = this;
or from XAML :
<phone:PhoneApplicationPage
.......
.......
DataContext="{Binding RelativeSource={RelativeSource Self}}"
/>
Item.cs:
public class Item
{
public string Name { get; set; }
}
MainPage.xaml:
<Grid x:Name="ContentPanel">
<ListBox x:Name="TotalItems"
ItemsSource="{Binding Items}"
VerticalAlignment="Top">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="Item :" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Vertical"
VerticalAlignment="Center"
Margin="0,10,0,0">
<TextBox x:Name="NewItemTextBox" />
<Button x:Name="AddNewItem"
Content="Add"
Click="AddNewItem_Click" />
</StackPanel>
</Grid>
MainPage.cs:
public ObservableCollection<Item> Items { get; set; }
public MainPage()
{
InitializeComponent();
Items = new ObservableCollection<Item> { new Item { Name = "Roman" } };
DataContext = this;
}
private void AddNewItem_Click(object sender, RoutedEventArgs e)
{
Items.Add(new Item { Name = NewItemTextBox.Text });
}
Make things simple, but not simpler!

Databind my Accordion control in Silverlight 4

I have been searching all over the web trying to find an example of databinding an Accordion control.
I have written a simple test app to try and databind, and I can get the headers to bind, but can't seem to figure out how to get the content to bind. Could someone help me out?
Here is my XAML:
<tk:Accordion HorizontalAlignment="Left" Margin="12,12,0,0" Name="accordion1" Width="181" Height="325" Background="White" VerticalAlignment="Top">
<tk:Accordion.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding MenuHeaderName}" />
</StackPanel>
</DataTemplate>
</tk:Accordion.ItemTemplate>
<tk:Accordion.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=MenuItems.MenuItemName}" />
</StackPanel>
</DataTemplate>
</tk:Accordion.ContentTemplate>
</tk:Accordion>
And here is my code behind:
public partial class MainPage : UserControl
{
public class MenuItem
{
public MenuItem(string name) { MenuItemName = name; }
public string MenuItemName { get; set; }
}
public class MenuHeader
{
public MenuHeader(string name)
{
MenuItems = new List<MenuItem>();
MenuHeaderName = name;
}
public string MenuHeaderName { get; set; }
public List<MenuItem> MenuItems { get; set; }
}
public MainPage()
{
InitializeComponent();
List<MenuHeader> menuHeaders = new List<MenuHeader>();
MenuHeader robots = new MenuHeader("Robots");
robots.MenuItems.Add(new MenuItem("Robots - Item 1"));
robots.MenuItems.Add(new MenuItem("Robots - Item 2"));
robots.MenuItems.Add(new MenuItem("Robots - Item 3"));
menuHeaders.Add(robots);
MenuHeader pirates = new MenuHeader("Pirates");
pirates.MenuItems.Add(new MenuItem("Pirates - Item 1"));
pirates.MenuItems.Add(new MenuItem("Pirates - Item 2"));
pirates.MenuItems.Add(new MenuItem("Pirates - Item 3"));
menuHeaders.Add(pirates);
accordion1.ItemsSource = menuHeaders;
}
}
Figured it out.
Here is the XAML that works...
<tk:Accordion HorizontalAlignment="Left" Margin="12,12,0,0" Name="accordion1" Width="181" Height="325" Background="White" VerticalAlignment="Top">
<tk:Accordion.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding MenuHeaderName}" />
</StackPanel>
</DataTemplate>
</tk:Accordion.ItemTemplate>
<tk:Accordion.ContentTemplate>
<DataTemplate>
<ListBox ItemsSource="{Binding MenuItems}" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MenuItemName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</tk:Accordion.ContentTemplate>
</tk:Accordion>

Resources