WinRT Binding data of ViewMode inside a DataTemplate - xaml

I wanted to bind data inside a DataTemplate that is stored in ViewModel. I've tried several ways but did not succeed and the solutions for WPF doesn't seems to work on WinRT like AncestorType Property of RelativeSource.
<Page.DataContext>
<local:ViewModel x:Name="ViewModel" />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ListView ItemsSource="{x:Bind ViewModel.names}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:mydatatype">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<!--Here I want a TextBlock to show the number-->
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
Here is the ViewModel
public class ViewModel
{
public int Number = 42;
public List<mydatatype> names = new List<mydatatype>();
public ViewModel()
{
names.Add(new mydatatype("name1"));
names.Add(new mydatatype("name2"));
}
}
public class mydatatype
{
public string Name { get; set; }
public mydatatype(string name)
{
this.Name = name;
}
}

You can access the DataTemplate of other objects by giving them a name and then referencing this. Using this technique you should be able to access its DataContext to bind to the viewmodel directly, even from within a DataTemplate
<Page x:Name="PageRoot">
<Page.DataContext>
<local:ViewModel x:Name="ViewModel" />
</Page.DataContext>
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainPanel">
<ListView ItemsSource="{x:Bind ViewModel.names}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:mydatatype">
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding DataContext.Name, ElementName=PageRoot}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Page>

Related

How to make the textblock text centered in a button with image and text if no image is available in WPF

I have a button with the image and textblock.
Buttons are created dynamically based on the values from the database.
Now for a particular value text is present and no image is there I want to show that text in the center of the button (horizontally and vertically), but it is not working.
Please find the xaml below:
<ItemsControl ItemsSource="{Binding CategoriesList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Width="100" Margin="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border CornerRadius="10" Background="Maroon">
<StackPanel Orientation="Vertical">
<Image Source="{Binding CategoryImagePath}" Height="50"></Image>
<TextBlock Text="{Binding CategoryName}" Height="20" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
If no image is available I want to show only the text on the button but it should be centered.
If there is Image then I make the Image and text both displayed but when the Image is not available the text is getting displayed but it is not in the center It moves to the top portion of the button.
You can use a DataTemplateSelector to select different templates depending on whether you have an image. Such a selector might look like this:
public sealed class ButtonTemplateSelector : DataTemplateSelector
{
/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when we have an image.
/// The value is set in XAML.
/// </summary>
public DataTemplate ImageTemplate { get; set; }
/// <summary>
/// Gets or sets the <see cref="DataTemplate"/> to use when we don't have an image.
/// The value is set in XAML.
/// </summary>
public DataTemplate NoImageTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
Category category = item as Category;
if (category != null)
{
return category.CategoryImagePath == null ? NoImageTemplate : ImageTemplate;
}
return base.SelectTemplate(item, container);
}
}
I'm assuming a model object something like this:
public class Category
{
public string CategoryImagePath { get; set; }
public string CategoryName { get; set; }
}
Create and initialize a ButtonTemplateSelector resource in your XAML, then reference it from your ItemsControl:
<Window
x:Class="WPF.MainWindow"
x:Name="self"
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:wpf="clr-namespace:WPF"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.Resources>
<wpf:ButtonTemplateSelector x:Key="ButtonTemplateSelector">
<wpf:ButtonTemplateSelector.ImageTemplate>
<DataTemplate DataType="wpf:Category">
<Button
Width="100"
Margin="5"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border CornerRadius="10" Background="Maroon">
<StackPanel Orientation="Vertical">
<Image
Source="{Binding CategoryImagePath}"
Height="50" />
<TextBlock
Foreground="White"
Text="{Binding CategoryName}"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</wpf:ButtonTemplateSelector.ImageTemplate>
<wpf:ButtonTemplateSelector.NoImageTemplate>
<DataTemplate DataType="wpf:Category">
<Button
Width="100"
Margin="5"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center">
<Button.Template>
<ControlTemplate>
<Border
CornerRadius="10"
Background="Maroon"
Height="70">
<TextBlock
Foreground="White"
Text="{Binding CategoryName}"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</wpf:ButtonTemplateSelector.NoImageTemplate>
</wpf:ButtonTemplateSelector>
</Grid.Resources>
<ItemsControl
DataContext="{Binding ElementName=self}"
ItemsSource="{Binding CategoriesList}"
ItemTemplateSelector="{StaticResource ButtonTemplateSelector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Window>
For completeness, the code-behind for the window:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
public IEnumerable<Category> CategoriesList { get; } = new List<Category>
{
new Category { CategoryName = "First", CategoryImagePath = "/Assets/Square.bmp" },
new Category { CategoryName = "Second", CategoryImagePath = null },
};
}
This shows up as follows, which I think is what you're asking:

Multiple DataTemplates with UWP MapItemsControl

I have a MapControl in UWP:
<maps:MapControl x:Name="BikeMap" ZoomLevel="17" Center="{Binding CenterPoint, Mode=TwoWay}">
<maps:MapItemsControl x:Name="MapItems" ItemsSource="{Binding BikePoints}"
ItemTemplate="{StaticResource BikePointTemplate}"/>
</maps:MapControl>
and am adding MapElements using XAML data templates, my ItemsSource is a list of simple objects.
But, UWP doesn't seem to provide a way to specify the DataType of a DataTemplate and the MapItemsControl doesn't have a property for setting a DataTemplateSelector.
Does anyone know how I can use multiple data templates with the MapItemsControl and have the relevent data template selected based on the object type within the ItemsSource?
MapItemsControl Class does not have a property for setting DataTemplateSelector. To achieve what you want, we can take advantage of ContentControl by setting it as the template content in DataTemplate and then using ContentControl.ContentTemplateSelector property to set DataTemplateSelector.
Following is a simple sample:
XAML:
<Page x:Class="UWPApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:UWPApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate x:Key="GreenDataTemplate">
<StackPanel Background="Green">
<TextBlock Margin="5"
Maps:MapControl.Location="{Binding Location}"
Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"
FontSize="20"
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="RedDataTemplate">
<StackPanel Background="Red">
<TextBlock Margin="5"
Maps:MapControl.Location="{Binding Location}"
Maps:MapControl.NormalizedAnchorPoint="0.5,0.5"
FontSize="20"
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<local:MyTemplateSelector x:Key="MyTemplateSelector" GreenTemplate="{StaticResource GreenDataTemplate}" RedTemplate="{StaticResource RedDataTemplate}" />
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Maps:MapControl x:Name="MyMap" MapServiceToken="MapServiceToken">
<Maps:MapItemsControl x:Name="MyMapItemsControl" ItemsSource="{Binding}">
<Maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource MyTemplateSelector}" />
</DataTemplate>
</Maps:MapItemsControl.ItemTemplate>
</Maps:MapItemsControl>
</Maps:MapControl>
</Grid>
</Page>
Code-Behind:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate GreenTemplate { get; set; }
public DataTemplate RedTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item != null)
{
if (item is GreenPOI)
{
return GreenTemplate;
}
return RedTemplate;
}
return null;
}
}
public class POI
{
public string Name { get; set; }
public Geopoint Location { get; set; }
}
public class GreenPOI : POI { }
public class RedPOI : POI { }
This is just for example. In the sample, I used two data template with different background and I create a custom DataTemplateSelector which can choose DataTemplate based on the object type. And if you have several object types, you can also refer to this answer: How to associate view with viewmodel or multiple DataTemplates for ViewModel?

XAML Gridview to add an item directly

I successfully coded an XAML Gridview to show list of items.
However, I want to add an [+(ADD ITEM)] button at the end of the Gridview.
The ADD button has should have a custom template (at least a default button) which is different from the content item.
My XAML source is below:
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource DataSource}}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick">
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}">
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Subject}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" Height="60" Margin="15,0,15,0" FontWeight="SemiBold"/>
<TextBlock Text="{Binding TargetDate}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10" FontSize="12"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<!--
Something like that..
<Button Content="+" x:Name="btnAdd" />
-->
</GridView>
And, how can I add a ADD button(grid item) to XAML? thanks
You can achieve that by using a DataTemplateSelector, basically what you need to do is :
define another class that will represent the GridView "addItem"
public class GridItem
{
public String Subject { get; set; }
public String TargetDate { get; set; }
}
public class AddGridItem : GridItem
{
public bool IsGridItem { get; set; }
}
Make sure that your GridView's ItemSource collection has always an AddGridItem in it
private ObservableCollection<GridItem> _gridItems =new ObservableCollection<GridItem>()
{
new GridItem()
{
Subject = "Subject1",
TargetDate = "TargetDate"
},new GridItem()
{
Subject = "Subject2",
TargetDate = "TargetDate"
},new GridItem()
{
Subject = "Subject3",
TargetDate = "TargetDate"
},new AddGridItem()
{
IsGridItem = true
}
};
public ObservableCollection<GridItem> GridItems
{
get
{
return _gridItems;
}
set
{
if (_gridItems == value)
{
return;
}
_gridItems = value;
}
}
Create a DataTemplateSelector class that will return the appropriate DataTemplate based on the Item type
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate RegularTemplate { get; set; }
public DataTemplate AddTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item,
DependencyObject container)
{
if (item is AddGridItem)
return AddTemplate;
if (item is GridItem)
return RegularTemplate;
return base.SelectTemplateCore(item, container);
}
}
Define your dataTempaltes and a DataTemplateSelector as staticresources to use them in your GridView
<Page.Resources>
<DataTemplate x:Key="RegularTemplate">
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border BorderThickness="3" BorderBrush="White">
<StackPanel VerticalAlignment="Bottom" Background="LightSkyBlue">
<TextBlock Text="{Binding Subject}" Style="{StaticResource BaseTextBlockStyle}" Height="60" Margin="15,0,15,0" FontWeight="SemiBold"/>
<TextBlock Text="{Binding TargetDate}" Style="{StaticResource BaseTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10" FontSize="12"/>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
<DataTemplate x:Key="AddItemTemplate">
<Border BorderThickness="3" BorderBrush="White" Background="DodgerBlue">
<FontIcon Glyph="" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White"/>
</Border>
</DataTemplate>
<local:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
RegularTemplate="{StaticResource RegularTemplate}"
AddTemplate="{StaticResource AddItemTemplate}">
</local:MyDataTemplateSelector>
</Page.Resources>
<Grid>
<GridView ItemsSource="{Binding GridItems}" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}">
</GridView>
</Grid>

Binding ListBox inside a listBox WP8

I need to bind a a listbox named cityListBox inside the ContryListBox with the following structure of class
public class Country
{
public Country();
public string ID { get; set; }
public List<City> LstCity { get; set; }
public string Title { get; set; }
}
i want that my outer listbox should come with Country Title as header and in the innner listBox City header where city is also a class with Id and Title
my xaml code:
<ListBox x:Name="ContryListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Bewise:ExpanderControl HeaderText="{Binding Title, Mode=OneWay}" >
<Bewise:ExpanderControl.ContentArea>
<ListBox x:Name="cityListBox " >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox></CheckBox>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Bewise:ExpanderControl.ContentArea>
</Bewise:ExpanderControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--Added ItemsSource binding-->
<ListBox x:Name="ContryListBox" ItemsSource="{Binding YourCountryListProperty}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Bewise:ExpanderControl HeaderText="{Binding Title, Mode=OneWay}" >
<Bewise:ExpanderControl.ContentArea>
<!--Added ItemsSource Binding-->
<ListBox x:Name="cityListBox" ItemsSource="{Binding LstCity}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox></CheckBox>
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Bewise:ExpanderControl.ContentArea>
</Bewise:ExpanderControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

How to Make Content Hidden in Expander Windows Phone Control

I am playing around with an example of Expander Control from Windows Phone Toolkit (I am using it for wp7).
When I load up the stripped down version everything seems expanded. When I click on Customer Pizza or 2 nothing happens. I would like the sub stuff to be collapsed but I don't know how.
<phone:PhoneApplicationPage
x:Class="ExpanderViewSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.Resources>
<toolkit:RelativeTimeConverter x:Key="RelativeTimeConverter"/>
<DataTemplate x:Key="CustomHeaderTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Stretch="None"/>
<TextBlock Text="{Binding Name}"
FontSize="{StaticResource PhoneFontSizeExtraLarge}"
FontFamily="{StaticResource PhoneFontFamilySemiLight}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CustomExpanderTemplate">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Image}" Stretch="None"/>
<TextBlock Foreground="{StaticResource PhoneSubtleBrush}" VerticalAlignment="Center"
FontSize="{StaticResource PhoneFontSizeNormal}">
<TextBlock.Text>
<Binding Path="DateAdded" Converter="{StaticResource RelativeTimeConverter}" StringFormat="Date added: {0}" />
</TextBlock.Text>
</TextBlock>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="WindowsPhoneGeek.com" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="ExpanderViewSample" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Grid.Row="0" x:Name="listBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:ExpanderView Header="{Binding}" Expander="{Binding}"
IsExpanded="False"
HeaderTemplate="{StaticResource CustomHeaderTemplate}"
ExpanderTemplate="{StaticResource CustomExpanderTemplate}"></toolkit:ExpanderView>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
List<CustomPizza> customPizzas = new List<CustomPizza>()
{
new CustomPizza()
{
Name = "Custom Pizza 1",
IsExpanded = false,
DateAdded = new DateTime(2010, 7, 8),
Image="Images/pizza1.png"
},
new CustomPizza() { Name = "Custom Pizza 2", DateAdded = new DateTime(2011, 2, 10), Image="Images/pizza2.png"}
};
this.listBox.ItemsSource = customPizzas;
// Important properties:
// IsExpanded
// Header
// Expander
// ItemsSource
// HeaderTemplate
// ExpanderTemplate
// ItemTemplate
// NonExpandableHeader
// IsNonExpandable
// NonExpandableHeaderTemplate
}
}
public class CustomPizza : INotifyPropertyChanged
{
private bool isExpanded;
public string Image
{
get;
set;
}
public string Name
{
get;
set;
}
public DateTime DateAdded
{
get;
set;
}
public bool IsExpanded
{
get
{
return this.isExpanded;
}
set
{
if (this.isExpanded != value)
{
this.isExpanded = value;
this.OnPropertyChanged("IsExpanded");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I also don't get what this really is for
ExpanderView Header="{Binding}" Expander="{Binding}"
I don't get what "binding" is referring too. It just seems to know which data to use but I don't know how it knows.
To change the expanded state of the expander view you can do the following
-register for tap event and add binding to IsExpanded (this will bind to the IsExpanded property of CustomPizza)
<toolkit:ExpanderView Header="{Binding}" Expander="{Binding}"
IsExpanded="{Binding IsExpanded}"
HeaderTemplate="{StaticResource CustomHeaderTemplate}"
ExpanderTemplate="{StaticResource CustomExpanderTemplate}"
Tap="expander_OnTap"></toolkit:ExpanderView>
-in the tap event switch the IsExpanded flag of the CustomPizza:
private void expander_OnTap(object sender, System.Windows.Input.GestureEventArgs e)
{
ExpanderView expander = sender as ExpanderView;
CustomPizza customPizza = expander.DataContext as CustomPizza;
customPizza.IsExpanded = !customPizza.IsExpanded;
}
Regarding the question about ExpanderView Header="{Binding}" Expander="{Binding}", when you set (or bind) the ItemsSource property of an ItemsControl to a list (ListBox is inheriting from a ItemsControl), the DataTemplate inside the ItemTemplate will be automatically set to each individual item. For example here you are setting it to a List of CustomPizza so each ItemTemplate DataContext will be a CustomPiza. So the ExpanderView will have the CustomPizza as DataContext. {Binding} will just pass the DataContext so like this whatever is inside the HEaderTemplate will get the same DataContext (CustomPizza ). If you had put {Binding Image} then the HeaderTemplate will just have the Image string as DataContext.