更改 DataContext 以进行 ControlTemplate 处理

Change DataContext for ControlTemplate handling

我有一个小应用程序,其中有一个模型树,我希望根据双击的项目,不同的视图应该出现在 ContentControl 中。 enter image description here

我创建了一个命令来更改 ContentControl 视图,但问题是 TreeView 的 DataContext 是“TreeItemModel”,其中我拥有显示树和子项的所有数据,但命令和视图处理在“MainViewModel”中编程,所以我不能 select 命令。 enter image description here

任何人都知道我该如何处理这个问题并能够继续使用我的 TreeItemModel 但 MainViewModel 来处理这个命令?

XAML代码:

        <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 代码:

    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;

        });

    }
}

最简单的方法是使用 RelativeSource 绑定:

            <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>

另一种解决方法是使用 Proxy class,它会将您的 DataContext 保存在变量中,例如 Proxy,请参阅:https://code.4noobz.net/wpf-mvvm-proxy-binding/