简体   繁体   English

WPF使用数据库处理click事件

[英]WPF handling click event with a database

I'm trying to get started with WPF at the moment. 我现在正试图开始使用WPF。 I have some experience with android and java, but i've never used C#. 我有一些android和java的经验,但我从未使用过C#。 I've set up a database, I established a connection with the database and used LINQ to create all the getters and setters for the database (Visual Studio), called databaselink.dbml. 我已经建立了一个数据库,我建立了与数据库的连接,并使用LINQ创建了数据库(Visual Studio)的所有getter和setter,名为databaselink.dbml。

I've created a simple register window (I know, passwords are not supposed to be in plain text nor should they be stored in variables, but this is simply to simplify the application, I have no intention of actually using this). 我创建了一个简单的注册窗口(我知道,密码不应该是纯文本,也不应该存储在变量中,但这只是为了简化应用程序,我无意实际使用它)。

<Window x:Class="Berichtensysteem.Window2"
        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:Berichtensysteem"
        mc:Ignorable="d"
        Title="Registreren" Height="300" Width="300"
        WindowState="Maximized">

    <Grid RenderTransformOrigin="0.494,0.507">

        <TextBox x:Name="username" HorizontalAlignment="Left" Height="23" Margin="144,92,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" />
        <TextBox x:Name="password" HorizontalAlignment="Left" Height="23" Margin="144,115,0,0"  VerticalAlignment="Top" Width="120" />
        <TextBox x:Name="passcon" HorizontalAlignment="Left" Height="23" Margin="144,138,0,0" VerticalAlignment="Top" Width="120" />
        <Button x:Name="register" Content="Registreren" HorizontalAlignment="Left" Margin="78,189,0,0" VerticalAlignment="Top" Width="120" Height="23"
        Click="register_click"

                />
        <TextBlock x:Name="usertxt" HorizontalAlignment="Left" Margin="23,93,0,0" Height="23" TextWrapping="Wrap" Text="Gebruikersnaam" VerticalAlignment="Top"/>
        <TextBlock x:Name="pwtxt" HorizontalAlignment="Left" Margin="23,116,0,0" Height="23" TextWrapping="Wrap" Text="Wachtwoord" VerticalAlignment="Top"/>
        <TextBlock x:Name="pwctxt" HorizontalAlignment="Left" Margin="23,138,0,0" Height="23" TextWrapping="Wrap" Text="Herhaal wachtwoord" VerticalAlignment="Top"/>
    </Grid>
</Window>

So I've set a click for my register button. 所以我点击了我的注册按钮。 My code, at the moment, looks like this: 我的代码目前看起来像这样:

namespace Berichtensysteem
{
    /// <summary>
    /// Interaction logic for Window2.xaml
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
        }

    private void register_Click(object sender, RoutedEventArgs e)
    {
        if (username.Text.Length == 0)
        {
            username.Text = "Geef gebruikersnaam in";
        }
        else if (password.Text.Length == 0)
        {
            password.Text = "Voer wachtwoord in";
        }
        else if (password != passcon)
        {
            password.Text = "Wachtwoorden niet gelijk";
        }
        else
        {
            string name = username.Text;
            string pass = password.Text;

            // See if user in database exists, add user to database if not.
        }
    }

    }
}

First of all, I renamed my window to 'Registerwindow.xaml' and Registerwindow.xaml.cs. 首先,我将窗口重命名为“Registerwindow.xaml”和Registerwindow.xaml.cs。 Nothing in my code changed, is this normal? 我的代码中没有更改,这是正常的吗? In android, the code gets refactored because the names have to be the same, is this not the case in WPF? 在android中,代码被重构,因为名称必须相同,这在WPF中不是这样吗?

My link class: 我的链接类:

#region Extensibility Method Definitions
partial void OnCreated();
partial void Insertemail(email instance);
partial void Updateemail(email instance);
partial void Deleteemail(email instance);
partial void Insertuser(user instance);
partial void Updateuser(user instance);
partial void Deleteuser(user instance);
partial void Inserttype(type instance);
partial void Updatetype(type instance);
partial void Deletetype(type instance);
partial void Insertrecipient(recipient instance);
partial void Updaterecipient(recipient instance);
partial void Deleterecipient(recipient instance);
#endregion

    public databaselinkDataContext() : 
            base(global::Berichtensysteem.Properties.Settings.Default.emaildatabaseConnectionString, mappingSource)
    {
        OnCreated();
    }

    public databaselinkDataContext(string connection) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }

    public databaselinkDataContext(System.Data.IDbConnection connection) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }

    public databaselinkDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }

    public databaselinkDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
            base(connection, mappingSource)
    {
        OnCreated();
    }

Could anyone help me on my way with this please? 拜托,请问有人帮我吗? If I have an example I can continue using it to do all the other database related stuff. 如果我有一个例子,我可以继续使用它来做所有其他数据库相关的东西。 Sorry if this seems silly. 对不起,如果这看起来很傻。

Oh, my question in case it wasn't clear: how do I now check if the user exists in my database, and add it if it doesn't. 哦,我的问题,以防不清楚:我现在如何检查用户是否存在于我的数据库中,如果不存在则添加它。

First of all, I renamed my window to 'Registerwindow.xaml' and Registerwindow.xaml.cs. 首先,我将窗口重命名为“Registerwindow.xaml”和Registerwindow.xaml.cs。 Nothing in my code changed, is this normal? 我的代码中没有更改,这是正常的吗? In android, the code gets refactored because the names have to be the same, is this not the case in WPF? 在android中,代码被重构,因为名称必须相同,这在WPF中不是这样吗?

File names have nothing to do with the compiled end results there is no link between the file name and the content at all, its best practice to have them named for the primary class inside but not required. 文件名与编译的最终结果无关,文件名和内容之间根本没有链接,最佳做法是将它们命名为主类,但不是必需的。 however if you are making any resource references these are to the file not the code so will break an example is 但是,如果您正在进行任何资源引用,那么这些是文件而不是代码,所以会打破一个例子

in the app.XAML 在app.XAML中

<Application x:Class="AppNamespace.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:AppNamespace"
             StartupUri="MainWindow.xaml" >
</Application>

here x:Class="AppNamespace.App" is a class reference so is unaffected by the file name but StartupUri="MainWindow.xaml" is a resource reference so would be affected by a change in filename 这里x:Class =“AppNamespace.App”是一个类引用,因此不受文件名的影响,但StartupUri =“MainWindow.xaml”是一个资源引用,因此会受到文件名更改的影响

in relation to your other question 与你的其他问题有关

i think firstly you need to review the basics of WPF, it is optimised to work with the MVVM pattern, the principle is fairly simple, you split your application into 3 layers 我认为首先你需要回顾一下WPF的基础知识,它是针对MVVM模式进行优化的,原理很简单,你将应用程序分成3层

the Data layer or Model: this layer handles access to external data such as web services, databases, save files, etc, this is the only thing this layer should do, it never talks to the front end Note if you have notification from external data sources about changes they are handled here. 数据层或模型:该层处理对外部数据的访问,例如Web服务,数据库,保存文件等,这是该层应该做的唯一事情,它从不与前端通信注意如果您有来自外部数据的通知关于他们在这里处理的变更的来源。

The Business layer or View Model, this layer handles all communcation between the Model and the View, this layers handles all business logic and informs the front end that it needs to update Note this doesn't have to be a 1 to 1 relationship 业务层或视图模型,该层处理模型和视图之间的所有通信,这些层处理所有业务逻辑并通知前端它需要更新注意这不必是1对1的关系

The Gui or View layer, this layer handles all formatting and user interaction when a users changes data the View passed those changes to the View Model, the view model will then decide when or if changes are passed to the model for saving Gui或View层,当用户更改数据时,该层处理所有格式和用户交互,View将这些更改传递给View Model,然后视图模型将决定何时或是否将更改传递给模型以进行保存

as a simple example 举个简单的例子

//Model possibly generated by LinqToSQL, Entity Framework or simalar, in which case most of this will be done for you automatically
public class Person
{
    public string FirstName{get;set}
    public string SurnameName{get;set}
    public DateTime DateOfBirth{get;set}
    public static Person Load()
    {
        //get person from DB
    }
    public void Save()
    {
        //copy record to DB
    }
}
//Read only ViewModel converts model into the required format INotifyPropertyChanged used to inform View about changes to class as notified by the model
public class PersonShort:INotifyPropertyChanged
{
    private Person model;
    public string Name{get;} => model.FirstName + " " + model.FirstName;
    public int Age => (DateTime.Today - model.DateOfBirth);

    public void Save()
    {
        //copy record to DB
    }
}
//Editable ViewModel converts model into the required format and allows editing with INotifyPropertyChanged used to inform View about changes to class as notified by the model or as a result from changes in the view, note that because the Person is held separately in the VM undoing is possible
public class PersonEdit:INotifyPropertyChanged
{
    private Person model;
    public string FirstName{get;set}
    public string SurnameName{get;set}
    public DateTime DateOfBirth{get;set}
    public string ValidationMessage{get;set}

    public void Save()
    {
       if(validatedata)
       {
           model.FirstName = Firstname;
           model.Surname = Surname;
           model.DateOfBirth= DateOfBirth;
           model.Save();
       }
    }
    public void Cancel()
    {
           FirstName = model.Firstname;
           Surname = model.Surname;
           DateOfBirth= model.DateOfBirth;
    }
}

you would then use databinding to connect your Gui to the viewmodel 然后,您将使用数据绑定将Gui连接到viewmodel

<Textbox Text={binding FirstName} />

once you have this set up correctly the problem you have becomes much simpler 一旦你正确设置了这个问题,你就会变得更加简单

you would feed your search criteria into your view, this will then be formatted and validated correctly (is it empty, is it a int when you are expecting strings, is it using one fired or 5, etc) by the ViewModel which will then pass it to your Model to execute the Query on the database, which if using EF or LinqToSQL would be something like 你会把你的搜索条件提供给你的视图,然后将通过ViewModel正确地格式化和验证它(它是空的,当你期望字符串时它是一个int,是使用一个被触发还是5,等等)它是你的模型在数据库上执行查询,如果使用EFLinqToSQL会是这样的

//perform string search
DbContext.Users.Any(u=>u.Username == SearchString);
//perform ID search
DbContext.Users.Find(UserID);
//Add new users
DbContext.Users.Add(new User(){//populate details});
DbContext.Save();

Your question as-is doesn't appear to be a WPF issue, it's about your data access layer. 您的问题原样似乎不是WPF问题,而是您的数据访问层。 You will want to do more research into LinqToSql, but to get you started. 您将需要对LinqToSql进行更多研究,但是为了帮助您入门。

else
{
    string name = username.Text;
    string pass = password.Text;

    using (var db = new databaselinkDataContext())
    {
        // x.Id is an example, I don't know the schema of your table.
        var user = db.user.Where(x => x.Id == name).SingleOrDefault();
        if (user == null)
            MessageBox.Show(String.Format("User '{0}' does not exist in the database.", name));

        // Again user.Password is an example, I don't know the schema of your table.
        if (user != null && user.Password != pass)
            MessageBox.Show("Password is invalid.");
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM