gpt4 book ai didi

c# - WPF 中的 View 和 View 模型

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

我一直在 WPF 中搞乱 MVVM,并有一个快速的问题要问人们。现在我有:

  • MainWindow 由 MenuBar 和 UserControl
  • 组成
  • UserControl(上面提到的)基本上包含一个网格。

  • 我根据需要在用户控件中公开对网格属性的访问,但用户控件一无所知,也不与主窗口交互。

    我还有一个名为 ViewModel 的类,它为我操作 MainWindow/UserControl。我的理解是 ViewModel 知道 View (MainWindow/UserControl) 以及如何操作它,而 View 通常对 ViewModel 一无所知。

    如果我有这个权利,这是我的问题:
  • 当我在 MainWindow MenuBar 上单击按钮时,我想执行操作。现在,这些操作必然会在 MainWindow 中说一个 EventHandler,而 EventHandler 实例化 ViewModel 并调用处理方法,如下所示:
    private void RunQueryMenuItemAdvClick(object pSender, RoutedEventArgs pRoutedEventArgs)
    {
    ViewModel vViewModel = new ViewModel(this);
    vViewModel.RunQuery();
    }

  • View 模型看起来像这样:
        public class ViewModel
    {
    private DataProvider fDataProvider;

    private MainWindow fMainWindow;

    private BackgroundWorker fQueryWorker = new BackgroundWorker();

    public ViewModel(MainWindow pMainWindow)
    {
    fDataProvider = new DataProvider();
    fMainWindow = pMainWindow;

    //Query Worker
    fQueryWorker.DoWork += QueryWorkerDoWork;
    fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
    }

    private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
    {
    fMainWindow.UserControl_Data.busyIndicator1.IsBusy = false;
    fMainWindow.UserControl_Data.DataToPresent = pRunWorkerCompletedEventArgs.Result;
    }

    private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
    {
    pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
    }

    public void RunQuery()
    {
    if (!fQueryWorker.IsBusy)
    {
    fMainWindow.UserControl_Data.busyIndicator1.IsBusy = true;
    fQueryWorker.RunWorkerAsync();
    }
    }
    }

    我在这里的方法是否离谱?

    编辑新解决方案:
    首先,感谢大家的回复。我想提供我的新解决方案。这可能不是 100% 的 MVVM,但它必须比我所拥有的至少好 80%!

    我的 View 模型:
        public class ViewModel : ObservableObject
    {
    private DataProvider fDataProvider;

    private BackgroundWorker fQueryWorker = new BackgroundWorker();


    public ViewModel()
    {
    fDataProvider = new DataProvider();

    //Query Worker
    fQueryWorker.DoWork += QueryWorkerDoWork;
    fQueryWorker.RunWorkerCompleted += QueryWorkerCompleted;
    }

    //This is my Command for the MainWindow.MenuItem to bind to to run a query
    RelayCommand fRunQueryCommand;
    public ICommand RunQueryCommand
    {
    get
    {
    if (this.fRunQueryCommand == null)
    {
    this.fRunQueryCommand = new RelayCommand(param => this.RunQuery(),
    param => true);
    }
    return this.fRunQueryCommand;
    }
    }

    //This is my Property for the UserControl.progressBar to bind to
    private bool fIsBusy;
    public bool IsBusy
    {
    get { return this.fIsBusy; }
    set
    {
    if (value != this.fIsBusy)
    {
    this.fIsBusy = value;
    OnPropertyChanged("IsBusy");
    }
    }
    }

    //This is my Property for the UserControl.gridControl.ItemSource to bind to
    private object fSource;
    public object Source
    {
    get { return this.fSource; }
    set
    {
    if (value != this.fSource)
    {
    this.fSource = value;
    OnPropertyChanged("Source");
    }
    }
    }

    private void QueryWorkerCompleted(object pSender, RunWorkerCompletedEventArgs pRunWorkerCompletedEventArgs)
    {
    this.IsBusy = false;
    Source = pRunWorkerCompletedEventArgs.Result;
    }

    private void QueryWorkerDoWork(object pSender, DoWorkEventArgs pDoWorkEventArgs)
    {
    pDoWorkEventArgs.Result = this.fDataProvider.GetParticipantsData();
    }

    public void RunQuery()
    {
    if (!fQueryWorker.IsBusy)
    {
    this.IsBusy = true;
    fQueryWorker.RunWorkerAsync();
    }
    }

    我已经从 MainWindow 和 UserControl 后面删除了我的所有代码,并将其替换为 XAML,以将我需要的元素绑定(bind)到 ViewModel 和 1 命令中的两个属性。随时提供关于我可能会或可能不会通过重构获得的额外反馈。 (除了缺少模型用法)。

    最佳答案

    你是 方式在这里离开基地。

  • 反过来说:View 知道 ViewModel,而 ViewModel 对 View 一无所知。
    在 ViewModel 中引用 MainWindow 和 UserControl 绝不是 MVVM。
  • 当您使用 MVVM 时,您通常没有点击处理程序。

  • 处理这种情况的正确方法如下:
  • 将 ViewModel 中的 ICommand 公开为属性。 MainWindow 可以将其按钮绑定(bind)到该命令。
  • 在 ViewModel 中调用命令时,执行 RunQuery ,但您只需设置 IsBusy在 ViewModel 上为 true。 UserControl 反过来将绑定(bind)到该属性。

  • 所有这些都通过设置 DataContext 来实现。将 View 转换为 ViewModel 的实例。

    关于c# - WPF 中的 View 和 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12392360/

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