有关页面的mvvm导航的两个问题

时间:2019-06-24 06:21:25

标签: c# wpf mvvm combobox navigation

我尝试了从EN到其他语言的模板翻译器(.doc)。

这是给我的。

我已经完成了简单的mvvm导航,为清楚了解我想要的内容,请查看图片。 UI

首先,我如何将ICommand从“ NextItem”按钮转换为当前更改的页面,该更改页面位于文本框中。从其他方面来看,我如何在MainView中为我的Button调用Translate()方法。 其次:如何将所有页面放在上侧窗口的组合框中的窗口上,然后从那里选择页面。

现在如何

<Button
    x:Name="ButtonSecondView"
    Width="200"
    Command="{Binding GoToSecondViewCommand}"
    Content="SecondView" />

<Button
    x:Name="ButtonNextItem"
    Grid.Row="2"
    Width="250"
    Command="{Binding NextRandomItem}"
    Content="Next item" />

在其中MyCollection的仅存根生成随机项(1个,3个等) 在那里,我可以在初始化页面时将一些参数转换为页面。

public MainViewModel()
{
    MyCollection = new MyCollection();
    CurrentViewModel = new FirstViewModel(this,MyCollection.GetRandomItem());
    PageList = MyCollection.GetList();
}

public ICommand GoToFirstViewCommand
    {
        get
        {
            return new RelayCommand(() => { CurrentViewModel = new FirstViewModel(this, MyCollection.GetRandomItem()); });
        }
    }

public ICommand GoToSecondViewCommand
    {
        get
        {
            return new RelayCommand(() => { CurrentViewModel = new SecondViewModel(this, MyCollection.GetRandomItem()); });
        }
    }

SecondViewModel中的ctor

public SecondViewModel(INotifyContentChanged contentChanged,string Parametrs)
{
    ContentChanged = contentChanged;
    TextContent = Parametrs;
}

对不起,我的英语太糟糕了

再一次:第一个问题。

所以我有很多页面(位于第3页),我需要单击页面底部和页面中的按钮,在当前页面中,从文本框中获取文本,并将此参数输入到我的方法中,例如Translate(string field1)。这适用于所有页面。如果我在“组合框”中选择要切换的页面,则可以执行相同的“单击”按钮,并在我的方法Translate(string field1)中从文本框中输入文本

1 个答案:

答案 0 :(得分:1)

要导航并将参数传递给相应的页面视图模型,我会坚持使用您的模式和所使用的构图。我介绍了一个合成容器,该容器将所有页面视图模型保存在Dictionary<string, IPageViewModel>中。因此,所有页面视图模型都必须实现此接口。作为键,我使用了页面视图模型的类型名称(例如nameof(FirstViewModel))。我还引入了一个名为PageNavigationParameter的新属性,该属性绑定到TextBox以便获取内容(应该将其传递给相应的页面视图模型)。

第二个Dictionary<string, string>将每个页面视图模型的显示名称(将在ComboBox中显示的页面名称)映射到实际的页面视图模型名称(与类名称匹配,例如{{ 1}})。这样,您可以通过类名称或从页面显示名称的导航范围中获取所需的页面视图模型。

要从nameof(FistViewModel)中选择页面,您可以执行以下操作:

  1. 在视图模型中创建页面名称的集合,并将其绑定到ComboBox
  2. ComboBox.ItemSource属性绑定到视图模型
  3. 在视图模型的属性更改时导航到页面

要使此示例正常工作,您需要一个所有页面视图模型都必须实现的通用接口(例如ComboBox.SelectedItem)。此界面必须至少包含class FirstViewModel : IPageViewModel

页面视图模型界面

PageNavigationParameter

主视图模型(使用合成)

interface IPageViewModel
{
  string PageNavigationParameter { get; set; }
}

具有跨页范围的控件必须将class MainViewModel { public MainViewModel() { // The Dictionary to get the page view model name // that maps to a page display name this.PageViewModelNameMap = new Dictionary<string, string>() { {"First Page", nameof(FirstViewModel)}, {"Second Page", nameof(SecondViewModel)} }; // The ComboBox's items source // that holds the page view model display names this.PageNames = new ObservableCollection<string>(this.PageViewModelNameMap.Keys); // The Dictionary that stores all page view models // that can be retrieved by the page view model type name this.PageViewModels = new Dictionary<string, IPageViewModel>() { {nameof(FirstViewModel), new FirstViewModel()}, {nameof(SecondViewModel), new SecondViewModel()} }; this.CurrentPageViewModel = this.PageViewModels[nameof(FirstViewModel)]; this.PageNavigationParameter = string.Empty; } // You can use this method as execute handler // for your NavigateToPage command too private void NavigateToPage(object parameter) { if (!(parameter is string pageName)) { return; } if (this.PageViewModelNameMap.TryGetValue(pageName, out string pageViewModelName) { if (this.PageViewModels.TryGetValue(pageViewModelName, out IPageViewModel pageViewModel) { pageViewModel.PageNavigationParameter = this.PageNavigationParameter; this CurrentPageViewModel = pageViewModel; } } } private bool CanExecuteNavigation(object parameter) => parameter is string destinationPageName && this.PageViewModelNameMap.Contains(destinationPageName); private void OnSelectedPageChanged(string selectedPageName) { NavigateToPage(selectedPageName); } private ObservableCollection<string> pageNames; public ObservableCollection<string> PageNames { get => this.pageNames; set { this.pageNames = value; OnPropertyChanged(); } } private string selectedPageName; public string SelectedPageName { get => this.selectedPageName; set { this.selectedPageName = value; OnPropertyChanged(); OnSelectedPageChanged(value); } } private string pageNavigationParameter; public string PageNavigationParameter { get => this.pageNavigationParameter; set { this.pageNavigationParameter= value; OnPropertyChanged(); } } private Dictionary<string, ViewModelBase> pageViewModels; public Dictionary<string, ViewModelBase> PageViewModels { get => this.pageViewModels; set { this.pageViewModels = value; OnPropertyChanged(); } } private Dictionary<string, string> pageViewModelNameMap; public Dictionary<string, string> PageViewModelNameMap { get => this.pageViewModelNameMap; set { this.pageViewModelNameMap = value; OnPropertyChanged(); } } private IPageViewModel currentPageViewModel; public IPageViewModel CurrentPageViewModel { get => this.currentPageViewModel; set { this.currentPageViewModel= value; OnPropertyChanged(); } } } 作为其MainViewModel

XAML代码段

DataContext

对于导航按钮命令,可以使用与执行委托处理程序相同的<!-- The page menu (DataContext is MainViewModel) --> <ComboBox SelectedItem="{Binding SelectedPageName}" ItemsSource="{Binding PageNames}" /> <!-- The navigation parameter TextBox (DataContext is MainViewModel) --> <TextBox Text="{Binding PageNavigationParameter}" /> 方法,可以与can执行处理程序使用MainViewModel.NavigateToPage()。因此,您现在有了一个导航命令(例如CanExecuteNavigation),该命令通过将页面显示名称传递为NavigateToPage来导航到目标页面。