none
Custom TabControl binding to a screen collection

    Question

  • I would like to create custom usercontrol with TabControl and dynamic TabItems (not static!) base on screen collection.
    I created a custom usercontrol with ListBox control:
     <ListBox Name="lbOrders" ItemsSource="{Binding Path=Value}" Grid.Column="1">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock x:Name="txtOrderDate" Text="{Binding Path=OrderDate}"></TextBlock>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    It's works.
    I have problem to create a TabControl. 
      <sdk:TabControl  Margin="10,10,10,10" Name="tabControl1" 
                             ItemsSource="{Binding Path=Value}">
                <sdk:TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=OrderDate}" />
                    </DataTemplate>
                </sdk:TabControl.ItemTemplate>
                
            </sdk:TabControl>
    I have error message: Unable to cast object of type "LightSwitchApplication.SalesOrderHeader' to type 'System.Windows.Controls.TabItem'
    Can you provide way how to configure binding to do this?  Am I missing a converter likes in Michael's article about TreeView control?
    Any help would be greatly appreciated.
    Saturday, January 21, 2012 10:46 AM

Answers

  • There is not way to cast an object to TabItem using DataTemplate-ing as far as I know. You have to do it be code. The converter Michael is using is for the Custom Control to handle threading issues. You will need this (or a similar for that matter) but you will have to add tab items by code. No way to cast in any way object to TabItem. It's an issue I have read about in silverlight.net in the past but I don't recall (or can retrieve) the specific article to redirect you.
    1+1 = 3 for large values of 1
    Saturday, January 21, 2012 12:06 PM

All replies

  • There is not way to cast an object to TabItem using DataTemplate-ing as far as I know. You have to do it be code. The converter Michael is using is for the Custom Control to handle threading issues. You will need this (or a similar for that matter) but you will have to add tab items by code. No way to cast in any way object to TabItem. It's an issue I have read about in silverlight.net in the past but I don't recall (or can retrieve) the specific article to redirect you.
    1+1 = 3 for large values of 1
    Saturday, January 21, 2012 12:06 PM
  • I found the article

    http://forums.silverlight.net/t/44291.aspx

    this should do it.


    1+1 = 3 for large values of 1
    Saturday, January 21, 2012 12:57 PM
  • Thank you for your explanation. Good to know that isn't my mistake :)

    Well, I've just created a specified converter for create TabItems.

     

    CustomTabControl.xaml

      <UserControl.Resources>
            <local:EntityCollectionValueConverter x:Key="EntityCollectionValueConverter" />
        </UserControl.Resources>
        
        <Grid x:Name="LayoutRoot" Background="PowderBlue">
            <sdk:TabControl  Margin="10,10,10,10" Name="tabControl1" 
                             ItemsSource="{Binding Path=Value, Converter={StaticResource EntityCollectionValueConverter}}">
                <sdk:TabControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=OrderDate}" />
                    </DataTemplate>
                </sdk:TabControl.ItemTemplate>
                
            </sdk:TabControl>
        </Grid>

     

    EntityCollectionValueConverter.cs

        public class EntityCollectionValueConverter : IValueConverter
        {
     
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                // Get entity collection
                   How do it from value ???? 
     
                // Create tab items
                List<TabItem> result = new List<TabItem>();
     
                foreach (IEntityObject entity in entities)
                {
                    result.Add(new TabItem()
                    {
                        Header = entity.Details.Properties["OrderDate"].Value,
                        Content = "Hello World!"
                    });
     
                }
     
     
                return result;
     
            }
     
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

    How I can entity collection from value ? Value has VisualCollection type in debuger.

    Any help would be greatly appreciated.

    Saturday, January 21, 2012 1:44 PM
  • If ypu plan to assign the collection as datasource then your datacontext is an IVisualCollection you can run through to collect the items to a list taking under consideration threading issues like Mike's converter demostrates.

    1+1 = 3 for large values of 1

    Saturday, January 21, 2012 2:10 PM
  • Yes, but Michael's converter isn't good for me.  

    Look:

    IEntityObject entity = value as IEntityObject;

     

    My value object isn't IEntityObject. It's VisualCollection.

    Do you have any idea?

     

    Saturday, January 21, 2012 2:16 PM
  • I know that's why I told you about IVisualCollection

     

     

    IVisualCollection collection = value as IVisualCollection
    
    collection.Details.Dispatcher.BeginInvoke(()=>{
      foreach(IEntityObject item in collection)
        //add to a list
    });


     


    1+1 = 3 for large values of 1
    Saturday, January 21, 2012 2:47 PM
  • Unfortunately my collection is still empty. What do I wrong? I'm binding to the same collection ListBox (without converter) and works.

    I'm filling the solution is near.

     

    Saturday, January 21, 2012 3:01 PM
  • I don't know what exactly is the problem but keep in mind you fill the list in a thread this means that you shound expect the list to be returned empty from the ValueConverter but it will be filled afterwards. Check if your IVisualCollection has items before calling the dispatcher. If it does everyting should be ok. Threading is your problem.

    1+1 = 3 for large values of 1

     

    !!! NOTICE: Make sure that in the threaded loop you add your items to an ObservableObjectCollection<TabItem> so that the whole concept works. I neglected to stress this point as Michael's converter demostrates it, but it's imperative for the whole value converter thing to work. And coming to think of it, this could most probably be your problem as I see that you use a simple list.



    Saturday, January 21, 2012 8:53 PM