gpt4 book ai didi

c# - 关于mvvm页面导航的两个问题

转载 作者:行者123 更新时间:2023-12-03 10:31:53 25 4
gpt4 key购买 nike

我正在尝试制作从 EN 到其他语言的模板翻译器 (.doc)。
这只是为了我。
我已经完成了简单的 mvvm 导航。为了清楚地了解我想要什么,请查看图片:
UI
第一个问题:如何将按钮“NextItem”中的 ICommand 转换为已更改 textBox 内项目的当前选定页面,否则如何从当前页面为 MainView 中的按钮调用 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 项等)的 stub 。
在那里,我可以在初始化时将一些参数转换为页面。
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 个),我需要单击底部的按钮,并在我的页面中。在我当前的页面中,我从 textBox 获取文本,并将这些参数输入到我的方法中,例如 Translate(string field1)。这适用于我想要的所有页面。如果我更改选择组合框项目的页面,我可以执行相同的按钮单击按钮,并在我的方法 Translate(string field1) 中输入来自 textBox 的文本。

最佳答案

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

一秒Dictionary<string, string>将每个页面 View 模型的显示名称(将在 ComboBox 中显示的页面名称)映射到实际的页面 View 模型名称(与类名匹配,例如 nameof(FistViewModel) )。这样,您可以通过类名或在导航范围内从页面显示名称获取所需的页面 View 模型。

ComboBox 中选择页面你可以这样做:

  • 在 View 模型中创建页面名称的集合并将其绑定(bind)到 ComboBox.ItemSource
  • 绑定(bind)ComboBox.SelectedItem View 模型的属性
  • 当 View 模型的属性改变时导航到页面


  • 为了使这个例子工作,你需要一个所有页面 View 模型都必须实现的通用接口(interface)(例如 class FirstViewModel : IPageViewModel )。此接口(interface)必须至少包含 PageNavigationParameter
    页面 View 模型界面
    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作为他们的 DataContext .

    XAML 片段
    <!-- The page menu (DataContext is MainViewModel) -->
    <ComboBox SelectedItem="{Binding SelectedPageName}" ItemsSource="{Binding PageNames}" />

    <!-- The navigation parameter TextBox (DataContext is MainViewModel) -->
    <TextBox Text="{Binding PageNavigationParameter}" />

    对于您的导航按钮命令,您可以使用相同的 MainViewModel.NavigateToPage()方法作为执行委托(delegate)处理程序和 CanExecuteNavigation作为可以执行的处理程序。因此,您现在有一个导航命令(例如 NavigateToPage )通过将页面显示名称传递为 CommandParameter 来导航到目标页面.

    关于c# - 关于mvvm页面导航的两个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56730816/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com