Click here to Skip to main content
14,733,039 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi
It is MVVM project. I have a ListBox with TabControls inside of it's items. TabItems are different for each TabControl and are binded from ViewModel:

<tabcontrol itemssource="{Binding Tabs}">
</tabcontrol>


Tabs are:
public ObservableCollection<TabItem> Tabs
{   get { return tabs;  }
    set {
        tabs = value;
        value.CollectionChanged += delegate
        {
            OnPropertyChanged("Tabs");
        };

        OnPropertyChanged("Tabs"); } }


Tabs are filled by the following way only once:

Tabs = new ObservableCollection<tabitem>();

if (details.Image != null || !String.IsNullOrEmpty(details.Summary))
                    Tabs.Add(new TabItem() { Header = "General Info", Content = new GeneralInfo() { DataContext = ItemDetails } });  ........... 6 different types</tabitem>


This is a bit info about what I have. Then I dinamically change DataContext's of this TabControls to simulate scrolling.

All info from ViewModel is binded into control, but there is a problem with TabControl. Headers are binded. but content doesnt. All headers are deselected and TabCntrol content area is empty.

I have tried to make TwoWayBinding on SelectedIndex and SelectedItem, but it doesnt help.... Seems SelectedIndex doesn't do anything that can select TabItem. And SelectedItem doesn't work,becuase as I think it has new reference after each changing of data context. Because TabControl.ItemsSource re-binds and new TabItems created.

Maybe someone solved same problem and knows solution?

Thanks
Posted

I tried to understand your problem and, I hope I guessed right.


If you work MVVM and you change DataContext's, you probably have a view-model that contains the different view-models and the code that changes the DataContext's.


Binding SelectedIndex or SelectedItem to the current view-model doesn't help since after the DataContext had been changed the original view-model (the view-model that you was bound to) has already gone.


Try to add another property to the view-model that hold the code that changes the DataContext's. This property can hold the SelectedIndex for the TabControl and, can be used when you change the DataContext's.

   
v2
Comments
Renat Khabibulin 13-Oct-11 18:30pm
   
You are right, main DataContext contains another DataContext's. But Header and Data (from that contexts) are binded correctly. Problem is only with SelectedItem. I have tried to add SelectedIndex into main DataContext and create TwoWay binding with TabControl.SelectedIndex, but it doesnt help
Shmuel Zang 13-Oct-11 19:11pm
   
It doesn't help to only bind the SelectedItem to a property in the view-model since the Binding works with INotifyPropertyChanged. The PropertyChanged event is raised when the property is changed and, that is the way the Binding knows to change the DependencyProperty's value.
When you change the DataContext's of the TabControl, there is no raise of the PropertyChanged event for the "SelectedItem" (the property with the stored SelectedItem value) property...
Try to set the SelectedItem of the TabControl when you change its DataContext.
Renat Khabibulin 13-Oct-11 19:36pm
   
I have tried force OnPropertyChanged("SelectedIndex") after DataContext's changed. Doesn't help. I select any Tab and begin change DataContext's, then while this process somehow SelectedIndex = -1...I just cant understand how...Seems that DataContext is not disconnected with another ListBoxItem where TabControl doesnt't has SelectedItem. And thanks to TwoWay binding, -1 from another ListBoxItem binds to DataContext and then to current TabControl
Shmuel Zang 13-Oct-11 19:59pm
   
That happens because your view-model's property gets the value of the changed TabControl's SelectedIndex (via the Binding), when it is changed.
Try to store the value of the "SelectedIndex" view-model's property, in a local variable, before you change the DataContext of the TabContol and, set the original value after the DataContext of the TabControl has been changed.
Renat Khabibulin 13-Oct-11 20:13pm
   
I remove TwoWay binding from SelectedIndex to prevent changes in DataContext. I have added following code that is called each time DataContext changed:
for (int i = 0; i < Tabs.Count; i++)
{
if (Tabs[i].IsSelected)
{
SelectedIndex = i;
OnPropertyChanged("Tabs");
OnPropertyChanged("SelectedIndex");
return;
}
}

SelectedIndex=0 (first tab), but NOTHING IS SELECTED!
Shmuel Zang 13-Oct-11 20:49pm
   
If you have the collection of the TabItem's, you can set the IsSelected property of the appropriate TabItem, according to the stored "SelectedIndex".
I have solved the my issue.
The problem was that I used controls as DataContext:
- List of TabItems
- Controls inside TabItems content
There was some processes, that I dont undrstand entire. But, idea is that while DataContext's changing, one DataContext can be assigned to 2 different TabControls. Since UI Controls cant belong to 2 parents at the same moment, so, binding that should show that controls from DataContext in content doesnt work. And doesnt throw excpetion (cause it's binding :) )

So, I remove al UI objects from DataContext, and add object models. And create UserControls that display are Views for these object models
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900