realistschuckle / wpfchrometabs

A WPF Control that duplicates the tabs found in Google Chrome.
MIT License
87 stars 38 forks source link

In ChromeTabControl, how to bind ItemsSource to an ObservableCollection<MyViewModel> ? #2

Closed gmoudry closed 10 years ago

gmoudry commented 11 years ago

Is it possible to use the MVVM Light framework and bind ChromeTabControl.ItemsSource to an ObservableCollection? I cannot get it to work - an exception is thrown - see below. I have zipped up a sample project here to illustrate the issue: https://skydrive.live.com/redir?resid=C5AC331FBA959883!141&authkey=!ALrLg9MbSyPXKQI

Here is my attempted XAML, taken from the zip:

    <chro:ChromeTabControl Name="tabGreen" 
                          ItemsSource="{Binding GreenModels}" SelectedItem="{Binding SelectedGreenTab}"
                           Grid.Row="4" Grid.Column="2">
   <!-- when I try to set ItemsSource="{Binding GreenModels}" below, 
    ChromeTabControl.cs get a InvalidCastException on line 179
    because this.Items entries, which is a GreenViewModel, cannot be cast to UIElement 
    -->
        <chro:ChromeTabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding IdStringShort}"/>
            </Style>
        </chro:ChromeTabControl.ItemContainerStyle>

        <chro:ChromeTabControl.Resources>
            <DataTemplate DataType="{x:Type vm:GreenViewModel}">
                <vu:GreenControl />
            </DataTemplate>
        </chro:ChromeTabControl.Resources>
    </chro:ChromeTabControl>
realistschuckle commented 10 years ago

@gmoudry I don't know, having never used the MVVM Light framework. However, when I get some time, I'll give a try and, if I can get it to work, then I'll shout back with a solution.

gmoudry commented 10 years ago

Thanks Curtis

In the meantime, I have come up with several hacks to ChromeTabControl. Hope to send you a patch submission next week.

Cheers Jiri

On Mon, Sep 23, 2013 at 10:53 AM, Curtis Schlak notifications@github.comwrote:

@gmoudry https://github.com/gmoudry I don't know, having never used the MVVM Light framework. However, when I get some time, I'll give a try and, if I can get it to work, then I'll shout back with a solution.

— Reply to this email directly or view it on GitHubhttps://github.com/realistschuckle/wpfchrometabs/issues/2#issuecomment-24906159 .

WPFTabs commented 10 years ago

@gmoudry I'm having the same issue. Did you find a solution?

gmoudry commented 10 years ago

Hi Curtis / Nicolas, both of you contacted me this week with Chrome Tabs questions.

I have reviewed my hack from last year. Last year, I could not figure out how to make binding work, so I used a hack - wrote code instead. Instead of binding, ViewModels for binding are cached in ViewModelLocator.s_hack_pendingOutputViewModels variable (I use MvvmLight framework).

Hope the example below helps - give me a shout if it doesn't. Good luck! Jiri

In Xaml designer of MainWindow I pasted a reference to ChromeTabs control as follows:

    <chro:ChromeTabControl Name="tabCtrl" Grid.Row="1">
        <chro:ChromeTabControl.Resources>
            <DataTemplate DataType="{x:Type vm:OutputViewModel}">
                <gui:CtrlOutput />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm:AViewModel}">
                <gui:CtrlA />
            </DataTemplate>
            <DataTemplate DataType="{x:Type vm:SViewModel}">
                <gui:CtrlS />
            </DataTemplate>
        </chro:ChromeTabControl.Resources>

        <chro:ChromeTabItem Header="Settings"

Background="Orange">

/gui:CtrlS /chro:ChromeTabItem /chro:ChromeTabControl In MainWindow.cs, I start listening for events from tab control: public MainWindow() { InitializeComponent(); tabCtrl.SelectionChanged += new SelectionChangedEventHandler(tabCtrl_SelectionChanged); _viewmodel = base.DataContext as MainWinViewModel; _viewmodel .Tabs.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Tabs_CollectionChanged); } ``` void Tabs_CollectionChanged(object sender, ``` System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { Trace.WriteLine("Adding " + e.NewItems.Count + " tabs"); foreach (IPageModel pageModel in e.NewItems) { if (pageModel is OutputViewModel) { OutputViewModeloutput = (OutputViewModel)pageModel; ViewModelLocator.s_hack_pendingOutputViewModels.Add(output); CtrlOutput ctrl = new CtrlOutput(); var itemToAdd = new ChromeTabs.ChromeTabItem { Header = EscapeUnderscore(pageModel.Title), Content = ctrl, }; this.tabMain.AddTab(itemToAdd, true); continue; } . . . in MainWindowViewModel I programatically add and remove child tabs but using an ObservableCollection Tabs. On Tue, Mar 18, 2014 at 4:20 PM, WPFTabs notifications@github.com wrote: > @gmoudry https://github.com/gmoudry I'm having the same issue. Did you > find a solution? > > ## > > Reply to this email directly or view it on GitHubhttps://github.com/realistschuckle/wpfchrometabs/issues/2#issuecomment-37953192 > .
sskodje commented 10 years ago

I modified this project for my own use recently, and i uploaded the finished project here. It's fully MVVM compatible and has some nifty new features added, like dragging tabs to and from windows.

realistschuckle commented 10 years ago

Hey, that's great! I'll add a note to the README to point over to your repo, in case folks are looking for that.