different content in each tabitem

Topics: Prism v2 - Silverlight 3
Nov 2, 2009 at 1:45 AM
Edited Nov 2, 2009 at 1:46 AM

Hi,

Here's my working model for the PRISM work I've been doing.

http://cid-9fdb2a0b191b39e2.skydrive.live.com/self.aspx/Public/PrismTab.Shell.zip

This works (all the files required are included in the zip file and the password for the login screen is 'test').

The data is set to show as a list (after the login screen). I want it to show as TabControl something like below:

Tab Header: Name Tab
Tab Content: <value in Name>

Tab Header: Word Tab
Tab Content: <value in Word>

Tab Header: Time Tab
Tab Content: <value in Time>

The data for each of the tab content will be completely different from the other. So I cannot just write a style for this that gets repeated across all tabs. How do I get this done?

If possible, please have a look at the source code and give me insights.

Thanks
Arun

Nov 2, 2009 at 2:08 PM
Edited Nov 2, 2009 at 3:12 PM

 

 

Just create different views and add them to your tab region.

 

<TabControl Regions:RegionManager.RegionName="TabRegion" 

HorizontalAlignment="Stretch" BorderBrush="{x:Null}"

Regions:TabControlRegionAdapter.ItemContainerStyle="{StaticResource WhateverTabStyle}"

VerticalAlignment="Stretch" />

 

Nov 2, 2009 at 2:51 PM

Robb, do you have a snippet for this?

Nov 2, 2009 at 3:19 PM

You create your tab region in the shell and add the views in a module to the tab region

    public class WhateverModule : IModule
    {
        private readonly IUnityContainer _container;
        private readonly IRegionManager _regionManager;

        public WhateverModule(IUnityContainer container, IRegionManager regionManager)
        {
            _container = container;
            _regionManager = regionManager;
        }

        #region IModule Members

        public void Initialize()
        {
            RegisterViewsAndServices();

            IRegion tabRegion = this._regionManager.Regions["TabRegion"];

            View1 view1 = this._container.Resolve<View1>();
            tabRegion.Add(view1, "View1");

            View2 view2 = this._container.Resolve<View2>();
            tabRegion.Add(view2, "View2");
        }

        protected void RegisterViewsAndServices()
        {

        }

        #endregion
    }

Nov 2, 2009 at 3:41 PM

Thanks Robb, makes sense now. I'll give this a try.

Thanks again
Arun

Nov 3, 2009 at 6:02 AM

Robb,

Things have changed slightly on my end.

Instead of using different views, I've decided to put all the content in Accordion control. It looks like below:

<controls:Accordion x:Name="AccordionPane" Grid.Row="0" Grid.Column="0">
    <controls:AccordionItem Header="Word" Content="Name" />
    <controls:AccordionItem Header="Word" Content="Word" />
    <controls:AccordionItem Header="Time" Content="Time" />
</controls:Accordion>

Now, when I set the DataContext of the MetricsView.xaml class to a view model, I'm doing that in the constructor like this:

public MetricsView(ServiceViewModel viewModel)
{
    InitializeComponent();
    DataContext = viewModel;
}

My view model contains a property called MetricsItems of type List<MetricsItem>. The class MetricsItem is defined below:

public class MetricsItem
{
    public string Name { get; set; }
    public string Word { get; set; }
    public string Time { get; set; }
}

How do I write the binding code to make sure these properties are set to the content of the AccordionItem?

Thanks
Arun

Nov 3, 2009 at 2:14 PM
Edited Nov 3, 2009 at 2:23 PM

    It would be something like this.

    Bind to the ItemSource
   
    <controls:Accordion ItemsSource="{StaticResource MetricsItemCollection}">
        <!--customize content appearance-->
        <controls:Accordion.ContentTemplate>
            <DataTemplate>
                <Border Background="Red">
                    <TextBlock Text="{Binding Content}"/>
                </Border>
            </DataTemplate>
        </controls:Accordion.ContentTemplate>
        <!--customzie header appearance-->
        <controls:Accordion.ItemContainerStyle>
            <Style TargetType="controls:AccordionItem">
                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Border Background="Azure">
                                <TextBlock Text="{Binding Header}"/>
                            </Border>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </controls:Accordion.ItemContainerStyle>
    </controls:Accordion>


    Add this to your viewmodel

    private MetricsItems metricsItemsCollection;
    public MetricsItems MetricsItemsCollection
    {
        get { return this.metricsItemsCollection; }

        set
        {
            this.metricsItemsCollection = value;
            this.OnPropertyChanged("MetricsItemsCollection");
        }
    }
 
    private void SomeMethod()
    {
        MetricsItems.AddItem(header, view)
    }
    
    
    Create a seperate class

    public class MetricsItems : ObservableCollection<MetricsItem>
    {
        public MetricsItems() { }

        public void AddItem(string header, FrameworkElement content)
        {
            this.Add(new MetricsItem { RequestId = requestId, Content = content});
        }
    }

    public class MetricsItem
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public MetricsItem(string header, FrameworkElement content)
        {
            this.Header = header;
            this.Content = content;
        }

        private string Header { get; set; };
       
        private FrameworkElement Content { get; set; }

    }

Nov 3, 2009 at 4:27 PM

Robb,

Thanks a lot for your help.

Arun