【问题标题】:WPF MVVM Navigate betweel views from the same hierarchical levelWPF MVVM 从同一层级导航 betweel 视图
【发布时间】:2017-04-02 19:02:35
【问题描述】:

我正在尝试制作一个主要用于学习MVVM的小程序。它是一个小型图书馆。

我有 4 个视图(和 4 个视图模型)。 MainWindow 是父视图,我在内容控件中显示其他 3 个视图。

另外 3 个子视图是 HomeView、BookManagingView、ReaderManagingView。

在 HomeView 中,我显示 2 个 ListView(一个带有阅读器,一个带有书籍),而在其他 2 个视图中,我编辑/添加书籍或阅读器。

在我的 HomeView 中,我也有 2 个按钮。当我单击按钮时,我想从 HomeView 切换到 BookManagingView 或 ReaderManagingView。

如果我试图从主窗口切换到任何视图,它可以工作。

我想要做的是从 HomeView 切换到 BookManagingView 或 ReaderManagingView。我怎样才能做到这一点?

主窗口:

    <Grid>
    <ContentControl Content="{Binding CurrentView}" Height="340" Width="500" />
    <Button x:Name="btnHomeView" Content="Home" Command="{Binding ChangeViewToHomeView, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="16,70,0,0" VerticalAlignment="Top" Width="75"/>
    <Button x:Name="btnBookManagingView" Content="Reader Options" Command="{Binding ChangeViewToReaderManagView,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="96,70,0,0" VerticalAlignment="Top" Width="92"/>
    <Button x:Name="btnReaderManagingView" Content="Books Options" Command="{Binding ChangeViewToBookManagView,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="193,70,0,0" VerticalAlignment="Top" Width="92"/>
</Grid>

主窗口虚拟机:

    public class MainWindowViewModel : ViewModelBase
{
    private object currentView;
    private HomeViewModel homeVM;
    private ReaderManagingViewModel readerManagingVM;
    private BookManagingViewModel bookManagingVM;


    public MainWindowViewModel()
    {
        homeVM = new HomeViewModel();
        readerManagingVM = new ReaderManagingViewModel();
        bookManagingVM = new BookManagingViewModel();
        CurrentView = homeVM;

        ChangeViewToHomeView = new DefCommand(DisplayHomeView);
        ChangeViewToReaderManagView = new DefCommand(DisplayReaderManagingView);
        ChangeViewToBookManagView = new DefCommand(DisplayBookManagingView);
    }

    public DefCommand ChangeViewToHomeView { get; private  set; }
    public DefCommand ChangeViewToReaderManagView { get; private set; }
    public DefCommand ChangeViewToBookManagView { get; private set; }


    public object CurrentView
    {
        get { return currentView; }
        set { currentView = value; RaisePropertyChanged(); }
    }

    public void DisplayHomeView()
    {
        CurrentView = homeVM;
    }

    public void DisplayReaderManagingView()
    {
        CurrentView = readerManagingVM;
    }

    public void DisplayBookManagingView()
    {
        CurrentView = bookManagingVM;
    }

主页视图:

<Grid>
    <ListView x:Name="listviewReaders" ItemsSource="{Binding ReadersList}" SelectedItem="{Binding SelectedReader, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="160" Margin="25,23,315,40">

...

    <ListView x:Name="listviewBooks" ItemsSource="{Binding BookList, Mode=OneWay}" SelectedItem="{Binding SelectedBook, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="160" Margin="316,50,24,117">

...

    <Button x:Name="btnEditReader" Command="{Binding EditReaderSwitch, UpdateSourceTrigger=PropertyChanged}" Content="EditR" HorizontalAlignment="Left" Margin="316,305,0,0" VerticalAlignment="Top" Width="74"/>
    <Button x:Name="btnEditBook" Command="{Binding EditBookSwitch, UpdateSourceTrigger=PropertyChanged}" Content="EditB" HorizontalAlignment="Left" Margin="402,305,0,0" VerticalAlignment="Top" Width="74"/>
</Grid>

家庭虚拟机:

 private Reader selectedReader;
    private Book selectedBook;
    private BookListFilter selectedFilter;

    private ObservableCollection<Book> bookList;
    private ObservableCollection<Reader> readerList;
    private IEnumerable<BookListFilter> bookLstItemSrc;

    public HomeViewModel()
    {
        SelectedReader = new Reader();
        SelectedBook = new Book();
        SelectedFilter = BookListFilter.AllBooks;

        BookDBDataContext rdb = new BookDBDataContext();

        ReadersList = new ObservableCollection<Reader>(rdb.Readers);
        GetBookList();

        EditReaderSwitch = new DefCommand(EditReaderInfo);
        EditBookSwitch = new DefCommand(EditBookInfo);
    }

    public DefCommand EditReaderSwitch { get; private set; }
    public DefCommand EditBookSwitch { get; private set; }
 private void EditBookInfo()
    {
        var tmpBook = new BookManagingViewModel(this);
        var tmpMwvm = new MainWindowViewModel();
        tmpMwvm.DisplayBookManagingView();
    }

    private void EditReaderInfo()
    {
        var tmpReader = new ReaderManagingViewModel(this);
        var tmpMwvm = new MainWindowViewModel();
        tmpMwvm.DisplayReaderManagingView();
    }

图书和阅读器管理视图有一堆文本框和按钮,用于添加、删除数据库。

Book & ReaderManagingVM 有添加/删除数据库的方法(现在它们是空的,如果我能先解决这个问题,我会完成它们)

我尝试使用 EditBook/ReaderSwitch 命令和 EditBook/ReaderInfo() 方法从 HomeView 导航到 Book/ReaderManagingView,但它不起作用。

我做错了什么,我应该怎么做才能解决它?

抱歉,帖子太长了。

【问题讨论】:

  • 看起来 Content 控件绑定到 CurrentView,但从您的 MainWindowVM CurrentView 实际上指向一个视图模型,而不是相应的视图(或显示 UI 的 XAML 控件)。 DisplayBookManagingView 方法实际上是做什么的?
  • 它将 CurrentView 更改为 BookManagingView(或者至少这就是我试图用它做的,它似乎有效)

标签: c# wpf mvvm


【解决方案1】:

您需要设置现有 MainWindowViewModel 实例的CurrentView 属性。现在您正在创建该类的 new 实例。

您可以使用MainWindowViewModel 注入HomeViewModel

private readonly MainWindowViewModel _x;
public HomeViewModel(MainWindowViewModel x)
{
    _x = x;
    SelectedReader = new Reader();
    ...
}

private void EditBookInfo()
{
    _x.DisplayBookManagingView();
}

MainWindowViewModel:

public MainWindowViewModel()
{
    homeVM = new HomeViewModel(this);
}

【讨论】:

  • 谢谢,我会试试这个。如果我仍然有问题,我应该在这里发帖还是问一个新问题?
猜你喜欢
  • 2013-11-08
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
相关资源
最近更新 更多