【问题标题】:Convert a simple WinForms app to WPF, specifically MVVM将简单的 WinForms 应用程序转换为 WPF,特别是 MVVM
【发布时间】:2017-08-18 10:34:54
【问题描述】:

背景:不久前,我在工作中创建了一个简单的 VB.NET WinForms 应用程序,它由一个表单和一个模块组成。该应用程序只是读取 Oracle 数据库并对其进行更新。

最近有人问我在创建应用程序时是否可以学习 C# WPF 和 MVVM。我认为这个应用程序足够简单,可以尝试转换,以便在我承担更具挑战性的项目时可以从中学习。我不得不承认我的日子很艰难。我想,如果我可以在应用程序的至少一个部分(连接/读取/验证数据库上的员工 ID)中正确设置 MVVM 部分,那么这种体验将使我能够自己完成其余的工作.我对 C# 没有太多经验,我不知道这里的模型和视图模型是否正确,或者是否需要颠倒它们。


目标:我要做的是在文本框中输入员工 ID,然后单击按钮。如果员工 ID 存在,请执行一些操作。如果没有,则显示一个消息框。

我首先在 IDE 中创建了三个文件夹:ModelViewViewModel。然后我创建了Model.csMainWindow.xamlViewModel.cs

我已经取得了足够的进展,可以让 Verify 公开课正常工作。但是,我不知道我是否完全正确地完成了它,并且显然我想要的行为没有发生。

Model.cs

namespace Wpf_BrazeKiosk.Model
{
    public class Model
    {

    }

    public class Verify
    {
        public const string ConnectionStringToORACLE = "Provider=OraOLEDB.Oracle.1;Data Source=MPCS;User ID=secret;Password=secret;";
        public OleDbDataReader rowread;
        public OleDbDataReader Emp_verify(string emp)
        {
            var conn = new OleDbConnection(ConnectionStringToORACLE);
            conn.Open();
            string query = "select employee_id from mpcs.employee where employee_id = ?";
            var cmd = new OleDbCommand(query, conn);
            cmd.Parameters.AddWithValue("employee_id", emp);
            rowread = cmd.ExecuteReader();
            return rowread;
        }
    }
}

ViewModel.cs

namespace Wpf_BrazeKiosk.ViewModel
{        
    public class ViewModel
    {
        private string _EmpID;
        public string EmpID
        {
            get
            {
                return _EmpID;
            }
            set
            {
                if (_EmpID == value)
                {
                    return;
                }
                _EmpID = value;
            }
        }
    }  
}

MainWindow.xaml

<Window x:Class="Wpf_BrazeKiosk.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Wpf_BrazeKiosk"
        mc:Ignorable="d"
        Title="MainWindow" Height="837" Width="1000">
    <Grid>
        <TextBox x:Name="textBox2" Height="23" Margin="444,423,416,0" TextWrapping="Wrap" Text="TextBox" Width="120" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <Button x:Name="button" Content="Remove" Margin="369,612,351,0" Width="260" Height="124" FontSize="20" VerticalAlignment="Top" HorizontalAlignment="Center"/>
    </Grid>
</Window>

【问题讨论】:

  • 问题是什么?你希望有人为你写剩下的 90-95% 吗?
  • WPF 是 UI 框架,MVVM 是分离不同“模块”中代码的模式/方法,由 WPF 强大的数据绑定完美支持。您可以重新设计您的 Winform 应用程序以使用 MVVM(Winform 也支持数据绑定,没有 WPF 强大,但足以满足您的应用程序)。然后您可以转移到 WPF,您只需更改 UI 代码并重用 Winforms 应用程序的相同视图模型/模型
  • @ASh 不,我不希望有人能写出 95%。我不知道还剩下 95%。我不打算从上到下重写我的整个问题。
  • 以上是我到目前为止所做的一切,只是为了让public class Verify 工作,但我不知道我是否做得正确,显然它不起作用。

标签: c# sql wpf oracle mvvm


【解决方案1】:

您应该将ICommand 属性添加到视图模型。有关命令及其用途的更多信息,请参阅以下博客文章:http://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/。如果您搜索它,可以在线获得有关 MVVM 和命令的更多信息。

完成此操作后,您只需将ButtonCommand 属性绑定到视图模型的ICommand 属性,并将TextBoxText 属性绑定到您的EmpID 属性:

<TextBox x:Name="textBox2" Text="{Binding EmpID}"/>
<Button x:Name="button" Content="Remove" Command="{Binding YourCommand}"/>

...并在命令的Execute 方法中实现您的逻辑,例如:

public class ViewModel
{
    public ViewModel()
    {
        YourCommandProperty = new DelegateCommand(Check);
    }
    private string _EmpID;
    public string EmpID
    {
        get
        {
            return _EmpID;
        }
        set
        {
            if (_EmpID == value)
            {
                return;
            }
            _EmpID = value;
        }
    }

    public ICommand YourCommandProperty { get; }

    private void Check(object o)
    {
        //look up EmpId here...
        MessageBox.Show("...");
    }
}

不要忘记将视图的 DataContext 设置为 ViewModel 类的实例:

public MainWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多