Hello,
I have a ListView with item template selector. Now user clicks on any item, DataTemplate of clicked item should change, without reading items source again. How to improve my code to meet such task.
<Page
...
> <Page.Resources>
<DataTemplate x:Key="XKSimpleDataTemplate" x:DataType="local:MyData">
<StackPanel Orientation="Horizontal">
<SymbolIcon x:Name="siInfo" Symbol="More"
PointerPressed="ChangeLinkDataTemplate_PointerPressed"
></SymbolIcon>
<TextBlock Text="{x:Bind data1}"></TextBlock>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="XKFullDataTemplate" x:DataType="local:MyData">
<StackPanel Orientation="Vertical">
<SymbolIcon x:Name="siInfo" Symbol="More"
PointerPressed="ChangeLinkDataTemplate_PointerPressed"
></SymbolIcon>
<TextBlock Text="{x:Bind data1}"></TextBlock>
<TextBlock Text="{x:Bind data2}"></TextBlock>
<TextBlock Text="{x:Bind data3}"></TextBlock>
</StackPanel>
</DataTemplate>
</Page.Resources>
<StackPanel>
<Button Content="Retrieve" Click="Retrieve_Click"></Button>
<ListView x:Name="lvMydata"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
>
<ListView.ItemTemplateSelector>
<local:MyDataTemplateSelector
SimpleDataTemplate="{StaticResource XKSimpleDataTemplate}"
FullDataTemplate="{StaticResource XKFullDataTemplate}"/>
</ListView.ItemTemplateSelector>
</ListView>
</StackPanel>
</Page>
Code Behind:
namespace ChangeDataTemplate_Test {
public sealed partial class MainPage : Page
{
ObservableCollection<MyData> ocMayData = new ObservableCollection<MyData>();
public MainPage()
{
this.InitializeComponent();
ocMayData.Add(new MyData("AAA", "BBB", "CCC"));
ocMayData.Add(new MyData("XXX", "YYY", "ZZZ"));
lvMydata.ItemsSource = ocMayData;
}
private void ChangeLinkDataTemplate_PointerPressed(object sender, PointerRoutedEventArgs e)
{
if (sender is SymbolIcon si)
if (si.Name == "siInfo")
{
//get item container
DependencyObject dpo = VisualTreeHelper.GetParent(si);
dpo = VisualTreeHelper.GetParent(dpo);
ListViewItem lvi = (ListViewItem)VisualTreeHelper.GetParent(dpo);
//set
if (lvMydata.ItemFromContainer(lvi) is MyData md)
{
md.IsOpened = !md.IsOpened;
//lvMydata.ItemTemplateSelector.SelectTemplate(lvi);
//alternative code
//if(lvMydata.ItemTemplateSelector is MyDataTemplateSelector mdts)
//mdts.SwitchTemplate(md);
}
}
}
private void Retrieve_Click(object sender, RoutedEventArgs e)
{
lvMydata.ItemsSource = null;
lvMydata.ItemsSource = ocMayData;
}
}
public class MyData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string data1;
public string data2;
public string data3;
private bool isOpened = false;
public bool IsOpened
{
get { return isOpened; }
set
{
if (value != isOpened && this.PropertyChanged != null)
{
isOpened = value;
this.PropertyChanged(this, new PropertyChangedEventArgs("IsOpened"));
}
else
isOpened = value;
}
}
public MyData(string data1 = null, string data2 = null, string data3 = null)
{
this.data1 = data1 ?? string.Empty;
this.data2 = data2 ?? string.Empty;
this.data3 = data3 ?? string.Empty;
}
}//End MyData
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate SimpleDataTemplate { get; set; }
public DataTemplate FullDataTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if (item is MyData md)
if (md.IsOpened == false)
return SimpleDataTemplate;
else
return FullDataTemplate;
else
return SimpleDataTemplate;
}
public void SwitchTemplate(object item)
{
if (item is MyData md)
if (md.IsOpened == false)
md.IsOpened = true;
else
md.IsOpened = false;
SelectTemplateCore(item);
} } }