C# 以编程方式从Content ViewModel更改ContentControl内容

C# 以编程方式从Content ViewModel更改ContentControl内容,c#,wpf,mvvm,contentcontrol,C#,Wpf,Mvvm,Contentcontrol,main window.xaml <Window.Resources> <DataTemplate DataType="{x:Type local2:StartPageViewModel}"> <local1:StartPage/> </DataTemplate> <DataTemplate DataType="{x:Type local2:SecondPageViewModel}">

main window.xaml

<Window.Resources>
    <DataTemplate DataType="{x:Type local2:StartPageViewModel}">
        <local1:StartPage/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local2:SecondPageViewModel}">
        <local1:SecondPage/>
    </DataTemplate>
</Window.Resources>
<DockPanel>
    <StackPanel DockPanel.Dock="Left">
        <Label Content="[res][per]" />
        <Button Command="{Binding CommandStartView}">
            First
        </Button>
        <Button Command="{Binding CommandSecondView}">
            Second
        </Button>            
    </StackPanel>
    <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
</DockPanel>
<StackPanel>
    <Label Content="First Page" />
    <Button Content="Second" Command="{Binding Path=DataContext.CommandSecondView, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
    <Button Content="Do Something" Command="{Binding CommandDoBeforeSecondView}"/>
</StackPanel>
StartPage.xaml

<Window.Resources>
    <DataTemplate DataType="{x:Type local2:StartPageViewModel}">
        <local1:StartPage/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type local2:SecondPageViewModel}">
        <local1:SecondPage/>
    </DataTemplate>
</Window.Resources>
<DockPanel>
    <StackPanel DockPanel.Dock="Left">
        <Label Content="[res][per]" />
        <Button Command="{Binding CommandStartView}">
            First
        </Button>
        <Button Command="{Binding CommandSecondView}">
            Second
        </Button>            
    </StackPanel>
    <ContentControl x:Name="Pages" DockPanel.Dock="Right" Content="{Binding SelectedViewModel}"/>
</DockPanel>
<StackPanel>
    <Label Content="First Page" />
    <Button Content="Second" Command="{Binding Path=DataContext.CommandSecondView, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
    <Button Content="Do Something" Command="{Binding CommandDoBeforeSecondView}"/>
</StackPanel>
问题: 如何使用开始页中的第二个按钮更改主窗口ContentControl中的内容?我想执行一些代码,然后更改内容

关于第一条评论,我想我必须在StartPageViewModel中添加一个对MainWindowViewModel的引用,我是如何做到这一点的

编辑

我的工作解决方案:

MainWindowViewModel.cs

private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
StartPageViewModel.cs

private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
我的工作解决方案:

MainWindowViewModel.cs

private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
StartPageViewModel.cs

private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
private void openStartView(object obj)
{
    SelectedViewModel = new StartPageViewModel(this);
}
class StartPageViewModel : BaseViewModel
{
    private MainWindowViewModel mainWindow;
    public ICommand CommandDoBeforeSecondView { get; set; }

    public StartPageViewModel(MainWindowViewModel _mainWindow)
    {
        mainWindow = _mainWindow;
        CommandDoBeforeSecondView = new RelayCommand(openSecondView);
    }

    private void openSecondView(object obj)
    {
        Console.WriteLine("DO SOME CODE");
        mainWindow.SelectedViewModel = new SecondPageViewModel();

    }
}
Thx致Peter Duniho,他回答了上述评论:

在MainWindowViewModel中创建StartPageViewModel时,只需传递该参数,StartPageViewModel就会有引用(当然,您必须将参数添加到构造函数中)


你的问题太模糊了,也太宽泛了。基于您共享的少量代码,您似乎已经有了视图模型的模板。您知道,将
SelectedViewModel
设置为不同的值将更改所使用的视图模型对象。那么,你的问题是什么?只需将该属性设置为您想要的任何值。只需为您的
StartPageViewModel
提供对
MainViewModel
对象的引用,或将
MainViewModel
对象订阅到
StartPageViewModel
上的适当事件,在该事件中,您可以通过该引用或事件来更改属性值。以上内容仍然不是一个问题。您有不需要的代码(
BoolToVisConverter
resource),并且缺少第二页代码(更不用说不是内置的
RelayCommand
)。根据您发布的内容,在
MainWindowViewModel
中创建
StartPageViewModel
时,只需传递
this
,然后
StartPageViewModel
将具有引用(当然,您必须将参数添加到构造函数中)。如果您希望能够在XAML中声明所有内容,另一种方法是只添加一个可以设置为正确值的属性。@PeterDuniho我将代码缩短为相关代码,但忘记删除
BoolToVisConverter
。第二页代码只是有一个标有“第二页”的标签。你试过我的建议吗?它们代表了将值从一个类传递到另一个类的两种最常见的方法。@PeterDuniho我试过了,它成功了,我在文章中添加了解决方案。