Reputation: 129
My goal is have each TabItem linked to a specific viewmodel. Furthermore, after transvering through each TabItem, the user input should not be reset. I am finding solutions for this and came across a potential solution but my testing failed me.
I have searched for answers and chose to do the following as it seems it applies the MVVM concept and it looks neat! However, I have a XAML binding error. I tried to replicate Jakob Christensen's answer provided in this link. I tried to debug and I think the issue is with the type of ObservableCollection that is created. It's an object type.
Thank you for helping!
This is the XAML code for my view
<TabControl>
<TabItem DataContext="{Binding TabList[0]}" x:Name="Tab1" Header="Tab1" Margin="-2,-2,-2,2" >
<Grid>
<TextBox x:Name ="EnterNum1" Margin="300,100,300,300" Text="{Binding test1, Mode =TwoWay}"/>
<Button Name="RunBtn1" Command="{Binding Path=RunBtn1, Mode=TwoWay}" Content="RUN" HorizontalAlignment="Right" Width="180" Height="40" FontSize="18"/>
</Grid>
</TabItem>
<TabItem DataContext="{Binding TabList[1]}" x:Name="Tab2" Header="Tab2" >
<Grid>
<TextBox x:Name ="EnterNum2" Margin="300,100,300,300" Text="{Binding test2, Mode =TwoWay}" Grid.Column="1"/>
<Button Name="RunBtn2" Command="{Binding Path=RunBtn2, Mode=TwoWay}" Content="RUN" HorizontalAlignment="Right" Width="180" Height="40" FontSize="18"/>
</Grid>
</TabItem>
</TabControl>
This is the XAML.cs for my view
public ObservableCollection<object> TabList { get; set; }
public ImportData()
{
InitializeComponent();
TabList = new ObservableCollection<object>();
TabList.Add(new SampleViewModel1());
TabList.Add(new SampleViewModel2());
}
Upvotes: 0
Views: 545
Reputation: 259
You should first set DataContext to TabControl or Window, then you can bind the TabItem to the viewmodel(TabList) list item
XAML
<TabControl>
<TabItem DataContext="{Binding TabList[0]}" x:Name="Tab1" Header="Tab1" Margin="-2,-2,-2,2" >
<Grid>
<TextBox x:Name ="EnterNum1" Margin="300,100,300,240" Text="{Binding Test1, Mode =TwoWay}"/>
<Button Name="RunBtn1" Command="{Binding Path=RunBtn1, Mode=TwoWay}" Content="RUN" HorizontalAlignment="Right" Width="180" Height="40" FontSize="18"/>
</Grid>
</TabItem>
<TabItem DataContext="{Binding TabList[1]}" x:Name="Tab2" Header="Tab2" >
<Grid>
<TextBox x:Name ="EnterNum2" Margin="300,100,300,240" Text="{Binding Test2, Mode =TwoWay}" Grid.Column="1"/>
<Button Name="RunBtn2" Command="{Binding Path=RunBtn2, Mode=TwoWay}" Content="RUN" HorizontalAlignment="Right" Width="180" Height="40" FontSize="18"/>
</Grid>
</TabItem>
</TabControl>
XAML.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AllViewModel allViewModel = new AllViewModel();
allViewModel.TabList = new ObservableCollection<object>();
allViewModel.TabList.Add(new SampleViewModel1());
allViewModel.TabList.Add(new SampleViewModel2());
this.DataContext = allViewModel;
}
}
public class AllViewModel : INotifyPropertyChanged
{
private ObservableCollection<object> tabList;
public ObservableCollection<object> TabList
{
get => tabList;
set { tabList = value;RaiseChange("TabList"); }
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SampleViewModel1 : INotifyPropertyChanged
{
private string test1 = "test1";
private ICommand runBtn1;
public string Test1
{
get => test1;
set { test1 = value;RaiseChange("Test1"); }
}
public ICommand RunBtn1
{
get => runBtn1;
set { runBtn1 = value;RaiseChange("RunBtn1"); }
}
public SampleViewModel1()
{
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SampleViewModel2 : INotifyPropertyChanged
{
private string test2 = "test2";
private ICommand runBtn2;
public string Test2
{
get => test2;
set { test2 = value; RaiseChange("Test2"); }
}
public ICommand RunBtn2
{
get => runBtn2;
set { runBtn2 = value; RaiseChange("RunBtn2"); }
}
public SampleViewModel2()
{
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
run result
Upvotes: 0