WPF 和 MVVM - 太多了

本文关键字:太多 MVVM WPF | 更新日期: 2023-09-27 18:30:19

所以我听说MVVM是在WPF中编码的方式。 我有某种视图模型。但是,如果您查看我目前拥有的代码片段,它会与 UI 紧密耦合,这就是我想分离的部分。

我的第一个挑战是通过 ViewModel 绑定所有控件,而不是直接在代码隐藏中设置它。

但这引出了一个问题。 我想知道我们应该使用 MVVM 样式获得多少细节。 我假设用户交互可以在是否显示字段的 UI 代码中最好地处理。但是,如果这仍然使它紧密耦合,那么MVVM方法可能是一个非常复杂的过程。在下面的代码片段中,我添加了注释来了解 UI 正在做什么。 UI 显示一个带有包含两个选项的单选按钮的窗口。一旦用户选择一个,就会出现 2 个组合框,隐藏/显示一些其他控件。在第一个组合中选择项目将填充第二个组合框。 从第二个组合中选择一个项目将生成一个代码以显示。某些控件是隐藏或显示的,具体取决于所选的单选按钮选项。

我很好奇如何实施 MVVM 以及多少是太多......

public partial class TaskCodeWin : Window
{
    // Object to bind the combobox selections to.
    private SACodeGeneratorViewModel.ViewModelComboBox _viewModelComboBox;
    private SACodeGeneratorViewModel.ViewModelLitComboBox _viewModelLitComboBox;
    public TaskCodeWin()
    {
      // Display the window, Users need to pick one practice choice
        InitializeComponent();
    }
    private string[] _practicearea = new string[] { "", "" };
    private void lblPracticeArea_Click(object sender, RoutedEventArgs e)
    {
        //Set the practice area and then ...
        if (!lblPracticeArea.IsChecked.Value)
        {
            _practicearea[0] = "STD1";
            _practicearea[1] = "STD2";
        }
        else
        {
            _practicearea[0] = "MA2";
            _practicearea[1] = "";
        }
        //...set the data on appropriate comboBoxes
        SetInitializationByPractice();
    }
    private void SetInitializationByPractice()
    {
        if (_practicearea[0].Equals("MA2"))
        {
            SourceMAContext();  //Use the correct VIEWMODEL context
            InitializeMAComboBoxes();  //Populate ComboBoxes using the above VIEWMODEL
            ShowHideActivityCode(Visibility.Hidden);  // Show or Hide controls as appropriate
        }
    }
    private void PopulateFirstDigitCombo()
    {
        _viewModelComboBox.LoadFirstDigit();
    }
    private string _firstDigit = String.Empty;
    private void cmbFirstDigit_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        // Users picks FirstDigit, then ...
        if (cmbFirstDigit.SelectedIndex >= 0)
        {
            _firstDigit = SetSecondDigitByPractice(); // ...populate the Second ComboBoxes using the appropriate VIEWMODEL
            displayTaskCode(); //Show the 3 digit combination code
        }
        cmbSecondDigit.SelectedIndex = -1;  
    }
    private string SetSecondDigitByPractice()
    {
        // When Users picks FirstDigit, then populate the Second ComboBoxes using the appropriate VIEWMODEL and selected FirstDigit
        if (_practicearea[0].Equals("MA2"))
        {
            return _viewModelComboBox.LoadSecondDigit(cmbFirstDigit.SelectedItem as object);
        }
        else
        {
            return _viewModelLitComboBox.LoadSecondDigit(cmbFirstDigit.SelectedItem as object);
        }
    }
    private string[] _codes;
    private string[] displayTaskCode()
    {
        _codes = new string[] {_firstDigit,_secondDigit };
        if (_firstDigit.Equals(String.Empty) || _firstDigit.Equals("-"))
        {
            _codes[0] = "-";
        }
        if (_secondDigit.Equals(String.Empty) || _secondDigit.Equals("-"))
        {
            _codes[1] = "-";
        }
        else
        {
            _codes[0] = "";
        }
        return _codes;
    }

    #region Properties
    private string[] practiceArea
    {
        get
        {
            return _practicearea;
        }
    }
    private string[] displayCode
    {
        get
        {
            return _codes;
        }
    }
    #endregion
}

WPF 和 MVVM - 太多了

MVVM 的黄金法则是 ViewModels 不得处理与 UI 相关的东西

因此,以下是开始使用 MVVM 模式的两个建议:

  • 分离 UI 控件(视图、用户控件...等)并将您的视图模型分成两个不同的程序集(包含 UI 内容的程序集引用包含视图模型的程序集)。这将创建一个强大的分离,防止在视图模型中对 UI 元素进行任何不必要的引用。
  • 如有必要,编写一些代码来处理纯UI内容,例如显示弹出窗口,管理焦点,拖放...等。

所以使用你的代码:

  • 基本上删除除构造函数之外的所有内容。添加一些内容来实例化您的视图模型(很可能在构造函数中this.DataContext = new YourViewModel();)。
  • 使用命令而不是事件处理程序,并在视图模型中执行关联的逻辑
  • 若要有条件地显示/隐藏 UI 元素,请使用绑定转换器(类似于 http://www.codeproject.com/Tips/285358/All-purpose-Boolean-to-Visibility-Converter)将元素的 Visibility 属性绑定到 ViewModel 的public bool属性。
  • 从视图模型公开ObservableCollections并使用绑定填充组合框
  • 等。