Search code examples
data-bindingpivotwin-universal-apppivotitem

Windows Universal App Pivot Binding and one Static PivotItem


I try to bind an pivot to the DataContext in an Windows Universal app. Everything works fine except it seems that I am unable to mix binding and "static" PivotItems. I need to create 0 to n PivotItems based on a list and on static PivotItem containing settings.

This is what I tried. If I remove the HeaderTemplate and ItemTemplate Element the PivotItem-Element is shown. If I let the Template Elements on there place the bound data is shown but not the extra PivotItem.

Is it even possible to mix?

<Pivot Name="PivotMain" Title="Title" ItemsSource="{Binding Path=Parts}">
            <Pivot.HeaderTemplate>
                <DataTemplate x:DataType="viewmodel:DetailModel">
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </Pivot.HeaderTemplate>
            <Pivot.ItemTemplate>
                <DataTemplate x:DataType="viewmodel:DetailModel">
                    <TextBlock Text="TestTest"/>
                </DataTemplate>
            </Pivot.ItemTemplate>
            <PivotItem Name="Settings" Header="Settings">
                <ScrollViewer VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
                    <ListView ItemsSource="{Binding Path=Settings}">
                        <ListView.ItemTemplate>
                            <DataTemplate x:DataType="viewmodel:SettingModel">
                                <RelativePanel>
                                    <ToggleSwitch Name="OnOff"
                                                  OffContent="{Binding OffContent}" OnContent="{Binding OnContent}" IsOn="{Binding IsMonitored, Mode=TwoWay}"
                                                  RelativePanel.AlignLeftWithPanel="True" />
                                </RelativePanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </ScrollViewer>
            </PivotItem>
        </Pivot>

Solution

  • Is it even possible to mix?

    As far as I known, it is impossible. But you can use other ways to meet your requirements. What you actually want to do is the first one PivotItem has different content with others. You should be able use a Data​Template​Selector that you can select a different DataTemplate for the first item (which header is settings) with others. For example, code as follows:

    XAML

    <Page.Resources>
       <DataTemplate x:Key="itemstemplate" x:DataType="local:DetailModel">
           <TextBlock Text="TestTest"/>
       </DataTemplate>
       <DataTemplate x:Key="settingtemplate" x:DataType="local:DetailModel">
           <ScrollViewer VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">
               <ListView ItemsSource="{Binding Path=Settingss}">
                   <ListView.ItemTemplate>
                       <DataTemplate x:DataType="local:SettingModel">
                           <RelativePanel>
                               <ToggleSwitch Name="OnOff" OffContent="{Binding OffContent}" OnContent="{Binding OnContent}" IsOn="{Binding IsMonitored, Mode=TwoWay}" RelativePanel.AlignLeftWithPanel="True" />
                           </RelativePanel>
                       </DataTemplate>
                   </ListView.ItemTemplate>
               </ListView>
           </ScrollViewer>
       </DataTemplate>
    
       <local:PivotTemplateSelector
           itemstemplate="{StaticResource itemstemplate}"
           settingtemplate="{StaticResource settingtemplate}"
           x:Key="PivotTemplateSelector" />
    </Page.Resources>
    
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
       <Pivot Name="PivotMain" Title="Title" ItemsSource="{Binding Path=Parts}"  ItemTemplateSelector="{StaticResource PivotTemplateSelector}">       
               <Pivot.HeaderTemplate>
               <DataTemplate x:DataType="local:DetailModel">
                   <TextBlock Text="{Binding Name}"/>
               </DataTemplate>
           </Pivot.HeaderTemplate>     
       </Pivot>
    </Grid>
    

    Code behind

    public sealed partial class MainPage : Page
    {
        ObservableCollection<DetailModel> Parts;
        ObservableCollection<SettingModel> Settingss;
        public MainPage()
        {
            this.InitializeComponent();
            Settingss = new ObservableCollection<SettingModel>()
            {
                new SettingModel()
                {
                     IsMonitored=true,
                     OffContent="work at",
                     OnContent="content"
                }
            };
            Parts = new ObservableCollection<DetailModel>()
            {
                new DetailModel()
                {
                    Name="Settings",
                    Settingss=Settingss
                },
                new DetailModel()
                {
                    Name="test1"
                },
                new DetailModel()
                {
                    Name="test2"
                }
            };
    
            datasources datasource = new datasources()
            {
                Parts = Parts
            };
            this.DataContext = datasource;
        }
    }
    public class PivotTemplateSelector : DataTemplateSelector
    {
        public DataTemplate itemstemplate { get; set; }
        public DataTemplate settingtemplate { get; set; }
    
        protected override DataTemplate SelectTemplateCore(object item)
        {
            DetailModel itemget = item as DetailModel;
            if (itemget.Name == "Settings")
            {
                return settingtemplate;
            }
            else
                return itemstemplate;
    
            return base.SelectTemplateCore(item);
        }
    
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            return SelectTemplateCore(item);
        }
    }
    public class datasources
    {
        public ObservableCollection<DetailModel> Parts { get; set; }
    }
    
    public class DetailModel
    {
        public string Name { get; set; }
    
        public ObservableCollection<SettingModel> Settingss { get; set; }
    }
    
    public class SettingModel
    {
        public string OffContent { get; set; }
        public string OnContent { get; set; }
        public bool IsMonitored { get; set; }
    }