I have a small App where I have a model tree and I want that depending the Item double clicked a different view should appear in the ContentControl. enter image description here
I have created a command to change the ContentControl view but the problem is that the DataContext of the TreeView is the "TreeItemModel" where I have all the data to show the tree and the childrens but the Command and the view handling are programmed in the "MainViewModel" so I can't select the command. enter image description here
Anyone has any idea how can I handle this issue and be able to continue using my TreeItemModel but the MainViewModel to handle this command?
XAML Code:
<Grid Grid.Row="3" Background="#FFF0F0F0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30*" MaxWidth="350"/>
<ColumnDefinition Width="70*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="5">
<TreeView x:Name ="TreeModel" ItemsSource="{Binding MainTree}" PreviewMouseDoubleClick="TreeView_PreviewMouseDoubleClick">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type model:TreeItemModel}" ItemsSource="{Binding Path=Elements}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.25*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding Path=Icon}" MaxHeight="30" MaxWidth="30" HorizontalAlignment="Left"/>
<TextBlock Grid.Column="1" Text="{Binding Path=Name}" Margin="5,0,0,0" HorizontalAlignment="Right" VerticalAlignment="Center"/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="commandBehaviors:MouseDoubleClick.Command" Value="{Binding DoubleClickCmd}"/>
<Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter" Value="{Binding}"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</StackPanel>
<ContentControl Grid.Column="1"
Margin="10"
Content="{Binding CurrentView}"/>
</Grid>
MainViewModel code:
class MainViewModel
{
// Command when double clicking in tree item
public RelayCommand DoubleClickCmd { get; set; }
string ObjPath;
public List<TreeItemModel> MainTree { get; set; }
public TreeItemModel MainObject { get; set; }
public VariablesViewModel VariableVM { get; set; }
private object _currentView;
public object CurrentView
{
get { return _currentView; }
set
{
_currentView = value;
OnPropertyChanged();
}
}
public MainViewModel()
{
VariableVM = new VariablesViewModel();
// Command that i want ot execute
DoubleClickCmd = new RelayCommand(o =>
{
CurrentView = VariableVM;
});
}
}
CodePudding user response:
The easies way is to use RelativeSource binding:
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="commandBehaviors:MouseDoubleClick.Command" Value="{Binding DataContext.DoubleClickCmd, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
<Setter Property="commandBehaviors:MouseDoubleClick.CommandParameter" Value="{Binding .}"/>
</Style>
</TreeView.ItemContainerStyle>
Another way to solve it is to use Proxy class which will hold your DataContext in variable for example of Proxy see this: https://code.4noobz.net/wpf-mvvm-proxy-binding/