C# MVVM理解问题

C# MVVM理解问题,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我向mvvm提出的一系列问题,您无需自行回答,我们非常感谢能够进一步帮助我的链接: 如果我有一个Mainpage.xaml文件,并且我使用的是viewmodelclass,那么Mainpage.xaml.cs文件中应该包含哪些代码?什么都没有 如果该代码段位于Mainpage.xaml.cs文件中: Viewmodel base=新的Viewmodel 如果我实现ICommands,我如何访问Mainpage.xaml上的textbox.text i命令完全替换按钮。是否单击事件?不是吗? 我尽

我向mvvm提出的一系列问题,您无需自行回答,我们非常感谢能够进一步帮助我的链接:

如果我有一个Mainpage.xaml文件,并且我使用的是viewmodelclass,那么Mainpage.xaml.cs文件中应该包含哪些代码?什么都没有

如果该代码段位于Mainpage.xaml.cs文件中:

Viewmodel base=新的Viewmodel

如果我实现ICommands,我如何访问Mainpage.xaml上的textbox.text

i命令完全替换按钮。是否单击事件?不是吗? 我尽量把代码保留到最低限度。我仍然倾向于将表单结束逻辑放在这里

许多人使用依赖注入从WPF表单外部完成这项工作

您可以将数据绑定到viewmodel上使用INotifyPropertyChanged的textbox.text的属性,并在viewmodel中对其进行修改。表单将自动更新以反映任何更改

是的,它将代码从表单抽象到viewmodel

YouTube上有一些很棒的视频详细解释了这些概念


希望这能有所帮助。

我认为你的问题表明你还没有真正开始用MVVM深入研究WPF

大多数入门教程都会解答您的问题。 我最喜欢的教程是乔希·史密斯的

这将为您提供所有问题的有效答案。不要忘了下载本文的代码示例,以获得完全工作的演示应用程序!:-

理想情况下,是的。但在大多数情况下,这很难理解 并非所有情况下都如此。如果ViewModel的构造函数不接受参数,可以用xaml编写:

<Window.Resources>
    <local:ViewModel x:Key="viewModel" /> <!-- this row will automatically create instance of ViewModel class-->
</Window.Resources>
在代码隐藏中

如果要遵循MVVM,请将TextBox的Text属性绑定到Viewmodel属性:

<TextBox Text="{Binding MyText}" />
public class MainWindowViewModel 
{
    public MainWindowViewModel()
    {
        LoginCommand = new DelegateCommand(Login);
    }

    public DelegateCommand LoginCommand { get; private set; }

    public string Username { get; set; }
    public string Password { get; set; }

    private void Login()
    {
        if (Username == "user" && Password == "user")
        {

        }
    }
}
然后,您可以使用RelayCommand或DelegateCommand google it来操作ViewModel中文本框的文本

对命令还允许将参数传递给ICommand,例如,当您将使用RelayCommand时
希望有帮助。

这个问题可能会因为不够具体而被删除,但还是这样吧

如果我有一个Mainpage.xaml文件,并且我使用的是viewmodelclass 代码应该在Mainpage.xaml.cs文件中吗?什么都没有

不只是MainPage,任何其他窗口或控件类,还有一些例外,我在这里将不介绍。您应该能够在不创建单个视图的情况下创建、运行和单元测试整个应用程序。viewmodels是您的应用程序,当您以需要用户交互(即,不是单元测试)的方式运行应用程序时,视图只是呈现给用户的松散绑定的图形UI表示

Viewmodel base=新的Viewmodel

这是一个有点复杂的主题,但高级答案是使用依赖注入框架。通过NuGet将MVVMLite添加到您的项目中会自动为您设置一个非常简单的框架,否则Google就是您的朋友

如果我实现ICommands,我如何访问例如textbox.text 在Mainpage.xaml上

使用getter和setter向视图模型添加字符串属性,并将textbox的文本属性绑定到该属性

i命令完全替换按钮。是否单击事件?不是吗

一般来说,是的。使用WPF的正确方法是将命令绑定到命令处理程序。添加事件处理程序的原因与添加属性getter和setter的原因相同,即帮助简化从旧WinForms方式的转换。仅仅因为框架支持它并不意味着它是处理事情的正确方式

如果我有一个Mainpage.xaml文件,并且我使用的是viewmodelclass 代码应该在Mainpage.xaml.cs文件中吗?什么都没有

您需要了解什么是视图以及viewmodel的职责。Codebehind是视图的一部分,所以只有视图职责涵盖的代码才应该在Codebehind中

有时在xaml中很难将数据绑定到viewmodel,例如PasswordBox,然后您可以使用codebehind获取密码或捕获更改并在viewmodel中设置属性。您不应该在codebehind中再次验证密码

有时很难在xaml中定义动画。您可以随意在C语言中创建或触发它们,但在这种情况下,您将无法在Expression Blend中编辑它们

可以在codebehind中使用像Loaded/Unload这样的even,例如,我使用它们来调用viewmodels中的Activate/Deactivate方法

这是codebehind示例,它不违反视图和viewmodel关注点的分离:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Closing += MainWindow_Closing;
    }

    MainWindowViewModel ViewModel
    {
        get { return (MainWindowViewModel)DataContext; }
    }

    void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        var canExit = ViewModel.ShowConfirmExitDlg();
        if (!canExit) e.Cancel = true;
    }
}
换句话说,有时候你必须使用代码隐藏。有人说,你不应该使用它,但要务实,使用它,当它帮助你

这段代码是否应该在Mainpage.xaml.cs文件中:Viewmodel base=newviewmodel

是的,没关系。但是,您应该在xaml中使用d:DataContext,以便 让VisualStudioDesigner知道您正在使用的datacontext,以便它能够为您提供intellisense和设计时支持。有很多方法可以设置InstanceViewModel并将其设置为datacontext。这取决于你选择什么

如果我实现ICommands,我如何访问Mainpage.xaml上的textbox.text

在viewmodel中创建字符串属性,并将textbox.text数据绑定到该属性。使用DelegateCommand,您可以在其中传递有权访问属性的方法:

<TextBox Text="{Binding MyText}" />
public class MainWindowViewModel 
{
    public MainWindowViewModel()
    {
        LoginCommand = new DelegateCommand(Login);
    }

    public DelegateCommand LoginCommand { get; private set; }

    public string Username { get; set; }
    public string Password { get; set; }

    private void Login()
    {
        if (Username == "user" && Password == "user")
        {

        }
    }
}
仅供参考,还有另一种向命令传递参数的方法:检查CommandParameter特性

i命令完全替换按钮。是否单击事件?不是吗


差不多。与回答第一个问题相同的规则也适用于这里。

我不知道是谁否定了这个问题,但我认为@Matthias从一个想要采用MVVM但没有以往经验的人的角度提出了非常有效的问题。我最近写了一篇关于MVVM最佳实践的文章,看看吧,我或多或少同意你在这里提出的所有观点。我刚刚用更多的细节和代码示例扩展了你的答案。所有非常好的观点,我唯一想问的是背后的代码。特别是,声明它不违反SOC。代码隐藏中的任何内容都不能进行单元测试,调用对话框的创建是合乎逻辑的,因此不应该出现在“无耻插件”视图中:有关此问题的讨论,请参阅我的文章。如果您实际上不需要单元测试,您当然可以不受影响,但从技术上讲,它确实打破了这种模式。我是在暗中做的。这与将textbox绑定到viewmodel属性相同。我可以在xaml中使用一些EventTriggers和CallMethod操作来完成它,但是这有什么区别呢?你会怎么做?@MarkFeldman:你能检查一下这个问题吗?