Hi Friends
I have 2 different user controls i.e.
ViewAUserControl.xaml
, and
ViewBUserControl.xaml
.
These controls are added dynamically in dynamic tabItems where each tabItem contains any single userControl from availabe 2 UserControls, whom names are mentioned above.
Problem is that I want to implement logic in ViewModel for each user control i.e for Button Click but when I mention DataContext in UserControl then StackOverFlow Exception Occurs.
What I have tried:
here is my <pre>ViewAUserControl.xaml
<UserControl x:Class="WpfPractice.View.ViewAUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfPractice.View"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<!--<UserControl.DataContext>
<local:ViewAUserControl></local:ViewAUserControl>
</UserControl.DataContext>-->
<Grid>
<Button Command="{Binding btnCmd}" Content="A" Height="30" Width="100"></Button>
</Grid>
</UserControl>
here is my
ViewBUserControl.xaml
<UserControl x:Class="WpfPractice.View.ViewBUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfPractice.View"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<!--<UserControl.DataContext>
<local:ViewBUserControl></local:ViewBUserControl>
</UserControl.DataContext>-->
<Grid>
<Button Command="{Binding btnCmd}" Content="B" Height="30" Width="100"></Button>
</Grid>
</UserControl>
here is Main Tab Window TabWindow.xaml
<Window x:Class="WpfPractice.View.TabWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:my="clr-namespace:WpfPractice.View"
xmlns:vm="clr-namespace:WpfPractice.ViewModel"
mc:Ignorable="d"
Title="TabWindow" Height="300" Width="300">
<Grid>
<Grid.Resources>
<vm:TabViewModel x:Key="TabVM"></vm:TabViewModel>
</Grid.Resources>
<TabControl x:Name="MyTabControl"
ItemsSource="{Binding TabViewModels}" DataContext="{StaticResource TabVM}"
SelectedItem="{Binding SelectedTabViewModel}" >
<TabControl.Resources>
<DataTemplate DataType="{x:Type vm:ViewModelA}">
<my:ViewAUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ViewModelB}">
<my:ViewBUserControl />
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Header}" />
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
</Grid>
</Window>
An Interface for each Controls's View Model
ITabViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfPractice.Model
{
public interface ITabViewModel
{
String Header { get; set; }
}
}
Main Tab's View Model TabViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfPractice.Model;
namespace WpfPractice.ViewModel
{
public class TabViewModel
{
public ObservableCollection<ITabViewModel> TabViewModels { get; set; }
public TabViewModel()
{
TabViewModels = new ObservableCollection<ITabViewModel> ();
TabViewModels.Add(new ViewModelA { Header = "Tab A" });
TabViewModels.Add(new ViewModelB { Header = "Tab B" });
TabViewModels.Add(new ViewModelA { Header = "Tab D" });
TabViewModels.Add(new ViewModelB { Header = "Tab E" });
}
}
}
View model for UserControlA ViewModelA.cs
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfPractice.Model;
namespace WpfPractice.ViewModel
{
public class ViewModelA : BindableBase, ITabViewModel
{
int count = 0;
DelegateCommand btnCmd;
string header;
public string Header { get=>header; set=>SetProperty(ref header, value); }
public ViewModelA()
{
btnCmd = new DelegateCommand(Execute);
}
bool canExecute()
{
return true;
}
void Execute()
{
Header = Header + (count++.ToString());
}
}
}
View model for UserControlB ViewModelB.cs
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WpfPractice.Model;
namespace WpfPractice.ViewModel
{
public class ViewModelB : BindableBase, ITabViewModel
{
int count = 0;
DelegateCommand btnCmd;
string header;
public string Header { get=>header; set=>SetProperty(ref header, value); }
public ViewModelB()
{
btnCmd = new DelegateCommand(Execute);
}
bool canExecute()
{
return true;
}
void Execute()
{
Header = Header + (count++.ToString());
}
}
}
Problem: I want to implement logic in ViewModel for each user control i.e for Button Click but when I mention DataContext in UserControl then StackOverFlow Exception Occurs. Kindly guide me to where bind DelegateCommand or ICommand ????