本文通过 11 个小案例强化 WPF 开发入门的基础。这 11 个案例是我从实际项目中抽象出来的,具有较强的实践意义,同时也能在很大程度上反映出 WPF 项目开发的一些基本概念。
1. 依赖注入以及动态打开 MainWindow
-
首先在 App.xaml 文件中删除
StartupUri="MainWindow.xaml"
这样就可以防止重复打开两个主窗口了。 -
然后为了成功的进行依赖注入,需要在
App.xaml.cs
文件中引入Microsoft.Extensions.DependencyInjection
. -
接下来就是创建一个静态公有的属性
ServiceProvider
. -
设置生命周期函数
OnStartup
, 在这个钩子函数中首先实例化一个 ServiceCollection 实例,使用此实例上的AddTransient
方法将 MainWindow 注册到依赖树上去。 -
serviceCollection 上提供一个名为 BuildServiceProvider 的方法,此方法返回一个获取依赖树上实例的方法 GetRequiredService.
-
完整的代码如下所示:
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
namespace wpfdemo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public static IServiceProvider ServiceProvider { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
ServiceProvider = serviceCollection.BuildServiceProvider();
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
private void ConfigureServices(IServiceCollection services)
{
// 添加 WPF 主窗口
services.AddTransient<MainWindow>();
}
}
}
2. 注册 sqlClient 服务,然后将依赖注入到 MainWindow 中去
- 创建一个文件夹 Services 用来放置所有需要注入的服务
mkdir Services
. - 在 Services 中创建文件
SqlClientService.cs
其内容如下:
首先使用 NuGet 中安装 System.Data.SqlClient
:
using System.Data;
using System.Data.SqlClient;
namespace wpfdemo.Services
{
public interface ISqlClientService
{
DataTable GetData(string query);
}
public class SqlClientService : ISqlClientService
{
private readonly string _connectionString;
public SqlClientService(string connectionString)
{
_connectionString = connectionString;
}
public DataTable GetData(string query)
{
using (SqlConnection connection = new SqlConnection(_connectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
DataTable dataTable = new DataTable();
adapter.Fill(dataTable);
return dataTable;
}
}
}
}
}
}
- 然后来到 App.xaml.cs 文件中,找到
ConfigureServices
函数,这个函数中已经注册了 Main Window 现在在其下面注册 ISqlClientService
private void ConfigureServices(IServiceCollection services)
{
// 添加 WPF 主窗口
services.AddTransient<MainWindow>();
// 注册数据库服务
services.AddTransient<ISqlClientService, SqlClientService>(provider =>
{
string connectionString = "Data Source=db.db;";
return new SqlClientService(connectionString);
});
}
可以看出来我们仍然使用 services.AddTransient<T>()
的方式注册服务的。
- 保持
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
不变;在文件 MainWindow.xaml.cs 中修改构造函数为:
private readonly ISqlClientService _sqlClientService;
public MainWindow(ISqlClientService sqlClientService)
{
InitializeComponent();
DataContext = new MainViewModel();
_sqlClientService = sqlClientService;
Console.WriteLine(_sqlClientService);
}
如果能够成功打印出来,就证明注入成功了。
3. DateRange 的实现
<TextBlock Grid.Column="0" Text="开始日期" VerticalAlignment="Center" FontSize="25" Foreground="White"/>
<hc:DatePicker Grid.Column="1" x:Name="startTime" ShowClearButton="False" Width="120" Height="40" Margin="10,0,30,0"/>
<TextBlock Grid.Column="2" Text="结束日期" VerticalAlignment="Center" FontSize="25" Foreground="White"/>
<hc:DatePicker Grid.Column="3" x:Name="endTime" ShowClearButton="False" Width="120" Height="40" Margin="10,0,30,0"/>
获取的数据做如下处理:
DateTime T1 = System.Convert.ToDateTime(startTime.Text);
DateTime T2 = System.Convert.ToDateTime(endTime.Text).AddDays(1); // 默认结束加1天
这样转换的目的就是利用 DateTime 实例是直接可以使用运算符进行大小比较的这种特性。
4. 使用 Grid 完成一个圣杯布局
<Grid Cursor="">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Grid 布局标题" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
<TextBlock Text="联系电话:17729563480" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
<Grid Grid.Row="1" Grid.Column="0" Background="Gray"></Grid>
<Grid Grid.Row="1" Grid.Column="2" Background="Gray"></Grid>
<TextBlock Text="这是一个圣杯布局,使用 WPF 中的 Grid 完成" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" FontWeight="Bold" FontFamily="Arial" Cursor="Pen" IsEnabled="False"></TextBlock>
</Grid>
5. 构造表格显示 List 中的数据
- 先构建 UI 界面,使用的是 DataGrid 控件,以及其中的名为
DataGrid.Columns
和DataGridTextColumn
DataGridCheckBoxColumn
的属性标签
<DataGrid x:Name="myDataGrid" AutoGenerateColumns="False" Grid.Row="1" Grid.Column="1" Margin="0,60,0,70" HorizontalAlignment="Center" Width="202">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"></DataGridTextColumn>
<DataGridTextColumn Header="Age" Binding="{Binding Age}"></DataGridTextColumn>
<DataGridCheckBoxColumn Header="Is Active" Binding="{Binding IsActive}"></DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
- 然后构建数据结构,在 Models 中创建
MainModel/MainModel.cs
文件:
namespace wpfdemo.MainModel
{
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsActive { get; set; }
}
}
- 最后在隐藏文件中构造 List 变量并将其绑定到 myDataGrid 上即可
using wpfdemo.MainModel;
...
public MainWindow()
{
InitializeComponent();
List<Person> persons = new List<Person>
{
new Person { Name = "John", Age = 30, IsActive = false},
new Person { Name = "Jane", Age = 20, IsActive = true},
}
myDataGrid.ItemSource = persons;
}
6. 创建自定义的组件库并引用
在 Visual Studio 中构建一个组件库项目,并在其他项目中引用它,是一个常见的开发需求。
步骤 1:创建组件库项目
-
打开 Visual Studio,选择 “创建新项目” 。
-
在项目类型中选择 “WPF 用户控件库” 或 “WPF 控件库” (.NET Framework 或 .NET Core/5+,根据你的目标框架选择)。
- 如果你使用的是 .NET Core 或 .NET 5+,选择 “WPF 控件库 (.NET Core)” 。
- 如果你使用的是 .NET Framework,选择 “WPF 控件库” 。
-
命名你的组件库项目(例如:
MyComponentLibrary
),然后点击 “创建” 。
步骤 2:开发组件库
在组件库项目中,你可以创建用户控件(UserControl)、自定义控件(CustomControl)或其他共享资源。
示例:创建一个简单的用户控件
-
在组件库项目中,右键点击项目,选择 “添加” -> “用户控件” 。
-
命名用户控件(例如:
MyCustomControl.xaml
),然后点击 “添加” 。 -
编辑用户控件的 XAML 和代码,例如:
xml复制
<!-- MyCustomControl.xaml --> <UserControl x:Class="MyComponentLibrary.MyCustomControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="200" Height="100"> <Grid> <TextBlock Text="Hello from My Custom Control!" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16" /> </Grid> </UserControl>
-
在代码后台(
MyCustomControl.xaml.cs
)中,你可以添加逻辑:csharp复制
namespace MyComponentLibrary { public partial class MyCustomControl : UserControl { public MyCustomControl() { InitializeComponent(); } } }
-
构建组件库项目,确保编译成功。
步骤 3:引用组件库
方法 1:通过项目引用(适用于同一解决方案中的项目)
-
在主项目中(例如:一个 WPF 应用程序),右键点击 “引用” ,选择 “添加引用” 。
-
在弹出的窗口中,切换到 “项目” 选项卡,找到你的组件库项目(
MyComponentLibrary
),勾选它,然后点击 “确定” 。 -
在主项目的 XAML 文件中,添加组件库的命名空间:
xml复制
<Window x:Class="MyApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:MyApp" xmlns:mylib="clr-namespace:MyComponentLibrary;assembly=MyComponentLibrary" Title="MainWindow" Height="450" Width="800"> <Grid> <mylib:MyCustomControl HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> </Window>
-
运行主项目,你应该能看到组件库中的控件显示在主项目中。
方法 2:通过 NuGet 包发布和引用(适用于跨解决方案的组件库)
-
打包组件库为 NuGet 包:
-
在组件库项目的根目录下,创建一个
.nuspec
文件(例如:MyComponentLibrary.nuspec
)。 -
编辑
.nuspec
文件,添加元数据:xml复制
<?xml version="1.0"?> <package> <metadata> <id>MyComponentLibrary</id> <version>1.0.0</version> <authors>YourName</authors> <owners>YourName</owners> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>My custom WPF component library</description> </metadata> </package>
-
使用命令行工具(如
nuget pack
)打包组件库:bash复制
nuget pack MyComponentLibrary.nuspec
-
这将生成一个
.nupkg
文件。
-
-
发布 NuGet 包:
- 将生成的
.nupkg
文件上传到 NuGet 官方仓库(nuget.org)或私有 NuGet 服务器。
- 将生成的
-
在主项目中引用 NuGet 包:
- 在主项目中,右键点击 “引用” ,选择 “管理 NuGet 包” 。
- 搜索你的组件库包(例如:
MyComponentLibrary
),安装它。 - 添加命名空间并使用组件,方法同上。
步骤 4:调试和更新组件库
-
调试组件库:
- 如果通过项目引用,直接在主项目中调试即可。
- 如果通过 NuGet 包引用,可以设置符号服务器或使用
#if DEBUG
条件编译符号。
-
更新组件库:
- 修改组件库代码后,重新编译。
- 如果通过项目引用,主项目会自动更新引用。
- 如果通过 NuGet 包引用,需要重新打包并更新 NuGet 包版本,然后在主项目中更新包。
总结
通过以上步骤,你可以轻松创建一个组件库项目,并在其他项目中引用它。选择项目引用或 NuGet 包引用,取决于你的具体需求和开发场景。
7. 自定义 dll 提供函数并使用
在自定义一个 DLL 类库并在 WPF 项目中使用其提供的函数时,需要完成以下技术细节:
一、创建类库项目
-
新建项目
- 在 Visual Studio 中,选择 “文件” -> “新建” -> “项目”。
- 选择 “类库” 项目模板,可以选择基于 .NET Framework 或 .NET Core/.NET 5+。
- 输入项目名称(如
YourLibraryNameSpace
),选择保存位置,点击 “创建”。
注意,为了方便演示,请将 dll 库项目不要和使用它的 WPF 项目放在同一个解决方案下面,这样有助于演示这个过程中的细节;如果已经在一个解决方案中了,也可以右击类库项目选择 “移除”。移除不会删除项目文件,只是不在同一个解决方案中了而已。
-
编写类库代码
- 在类库项目中,编写实现所需功能的代码。例如,一个简单的计算器功能:
namespace YourLibraryNamespace
{
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public int Subtract(int a, int b)
{
return a - b;
}
}
}
-
生成 DLL 文件
- 构建类库项目,生成的 DLL 文件将位于项目的输出目录(通常是
bin\Debug
或bin\Release
)。这个过程是自动的,无须点击多余按钮。
- 构建类库项目,生成的 DLL 文件将位于项目的输出目录(通常是
二、在 WPF 项目中引用类库
-
引用 DLL 文件
- 在 WPF 项目中,右键点击 “依赖项” 节点,“添加项目引用”节点,“浏览”,再点击“浏览”,输入 dll 文件的地址。
-
使用类库中的函数
- 在 WPF 项目的代码文件中,添加对类库命名空间的引用:
using YourLibraryNamespace;
- 然后,可以实例化类库中的类并使用其方法:
Calculator calculator = new Calculator();
int result = calculator.Add(2, 3);
8. 加载配置文件
- 环境构造
在项目根目录下创建 ConfigFiles
文件夹,然后在其中构建 AppSettings.json
文件:
{
"ConnectionStrings": {
"Sqlite": "Data Source=db.sqlite;"
}
}
这个文件需要参与运行,因此找到项目的 .csproj
文件,在其中将这个文件设置为运行时资源:
<ItemGroup>
<Resource Include="my.ico" />
<Content Include="ConfigFiles\AppSettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
- 然后再安装必要的依赖
Microsoft.Extensions.Configuration.Json
- 最后在 App.cs 的 OnStartup 钩子中将配置加载到 builder 中,然后打印出来
using Microsoft.Extensions.Configuration;
...
...
protected override void OnStartup(StartupEventArgs e)
{
...
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder
.AddJsonFile("./ConfigFiles/AppSettings.json", optional: false, reloadOnChange: false);
var configuration = configurationBuilder.Build();
string ConnectionString = configuration["ConnectionStrings:Sqlite"];
Console.WriteLine(ConnectionString);
}
这个功能是通过 ConfigurationBuilder 类实现的,在上面的代码中我们读取了 sqlite 的配置文件。
9. 读取 json 中的数据并使用其初始化 VM 对象
- 创建 View Model 类
namespace wpfdemo.ViewModels
{
public class MainViewModel
{
[Newtonsoft.Json.JsonIgnore] public string ConfigPath { get; set; } = "./ConfigFiles/MainWindowSettings.json";
// 属性示例
private string _message = "你好 WPF";
public string Message
{
get => _message;
set
{
if (_message != value)
{
_message = value;
}
}
}
}
}
这里设置了一个无需序列化的属性 ConfigPath 用来作为初始化配置文件路径。
- 创建
./ConfigFiles/MainWindowSettings.json
文件,并使其格式和MainViewModel
保持一致
{
"Message": "来自配置文件:你好 WPF"
}
- 然后在
MainWindow
视图层文件中将 json 中的数据拷贝给 VM 对象,然后再将 VM 对象指向DataContext
.
mainViewModel = new MainViewModel();
if (!FileExtensions.DoesFileExist(mainViewModel.ConfigPath))//如果为空,先自动创建一个
FileExtensions.WriteObject(mainViewModel.ConfigPath, new { });
//使用反射方法加载配置信息
FileExtensions.ReadObject<MainViewModel>(mainViewModel.ConfigPath).CopyPropertiesTo(mainViewModel);
DataContext = mainViewModel;
上述代码中做了防错处理,防止配置文件不存在的情况出现。
- 扩展 FileExtensions 类,在其中增加
DoesFileExist
,WriteObject
,ReadObject
和CopyPropertiesTo
方法
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace wpfdemo.Models.Core
{
public static class FileExtensions
{
// 将对象序列化为 JSON 并保存到文件
public static void WriteObject<T>(string filePath, T obj)
{
string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
File.WriteAllText(filePath, json);
}
// 将对象序列化为 JSON 并保存到文件(带自定义 Serializer Settings)
public static void WriteObject<T>(string filePath, T obj, JsonSerializerSettings settings)
{
string json = JsonConvert.SerializeObject(obj, settings);
File.WriteAllText(filePath, json);
}
// 从文件中读取 JSON 并反序列化为指定类型的对象
public static T ReadObject<T>(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File not found.", filePath);
string json = File.ReadAllText(filePath);
return JsonConvert.DeserializeObject<T>(json);
}
// 从文件中读取 JSON 并反序列化为动态对象(非泛型)
public static dynamic ReadObject(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File not found.", filePath);
string json = File.ReadAllText(filePath);
return JsonConvert.DeserializeObject(json);
}
// 检查文件是否存在
public static bool DoesFileExist(string filePath)
{
return File.Exists(filePath);
}
// 判断文件是否为空
public static bool IsFileEmpty(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File not found.", filePath);
return new FileInfo(filePath).Length == 0;
}
// 获取文件内容
public static string ReadAllText(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File not found.", filePath);
return File.ReadAllText(filePath);
}
// 拷贝文件
public static void CopyFile(string sourcePath, string destinationPath, bool overwrite)
{
if (!File.Exists(sourcePath))
throw new FileNotFoundException("Source file not found.", sourcePath);
File.Copy(sourcePath, destinationPath, overwrite);
}
// 删除文件
public static void DeleteFile(string filePath)
{
if (File.Exists(filePath))
File.Delete(filePath);
}
// 获取文件大小
public static long GetFileSize(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("File not found.", filePath);
return new FileInfo(filePath).Length;
}
// 将对象的属性值复制到另一个对象
public static void CopyPropertiesTo(this object source, object target)
{
if (source == null || target == null)
throw new ArgumentNullException("Source or target object is null.");
Type sourceType = source.GetType();
Type targetType = target.GetType();
foreach (PropertyInfo sourceProperty in sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (sourceProperty.CanRead)
{
PropertyInfo targetProperty = targetType.GetProperty(sourceProperty.Name, BindingFlags.Public | BindingFlags.Instance);
if (targetProperty != null && targetProperty.CanWrite)
{
if (sourceProperty.PropertyType.IsGenericType && sourceProperty.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
Type nullableType = sourceProperty.PropertyType;
Type underlyingType = Nullable.GetUnderlyingType(nullableType);
object value = sourceProperty.GetValue(source);
if (value != null)
{
if (targetProperty.PropertyType != underlyingType)
continue;
targetProperty.SetValue(target, Convert.ChangeType(value, underlyingType));
}
else
{
targetProperty.SetValue(target, null);
}
}
else
{
if (sourceProperty.PropertyType != targetProperty.PropertyType)
continue;
object value = sourceProperty.GetValue(source);
targetProperty.SetValue(target, value);
}
}
}
}
}
}
}
10. 连接到 Sqlite 数据库并使用
- 安装 SqlSugar 和 System.Data.SQLite
- 从配置文件中读取连接本地数据库的 connectionstring 然后将单例注入,并完成数据库的初始化
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using wpfdemo.Services;
using Microsoft.Extensions.Configuration;
using SqlSugar;
using wpfdemo.Models.Core;
using System.IO;
using wpfdemo.Models.Vision;
namespace wpfdemo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public static IServiceProvider ServiceProvider { get; private set; }
protected override void OnStartup(StartupEventArgs e)
{
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder
.AddJsonFile("./ConfigFiles/AppSettings.json", optional: false, reloadOnChange: false);
var configuration = configurationBuilder.Build();
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
serviceCollection.AddScoped<ISqlSugarClient>(s =>
{
//Scoped用SqlSugarClient
SqlSugarClient sqlSugar = new SqlSugarClient(new ConnectionConfig()
{
DbType = SqlSugar.DbType.Sqlite,
ConnectionString = configuration["ConnectionStrings:Sqlite"],
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
},
db =>
{
db.Aop.OnLogExecuting = (sql, pars) => { };
});
return sqlSugar;
});
ServiceProvider = serviceCollection.BuildServiceProvider();
if (FileExtensions.DoesFileExist("db.sqlite"))//如果数据库文件过大,重命名一下
{
long fileSize = FileExtensions.ReadAllText("db.sqlite").Length;
var sizeGB = fileSize * 1.0 / (1024 * 1024);
if (sizeGB > 3)//超过3个G自动重命名
{
File.Move("db.sqlite", $"db{DateTime.Today.ToString("yyyyMMddHHmmss")}.sqlite");
}
}
InitDatabase(ServiceProvider);
var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
private void InitDatabase(IServiceProvider service)
{
var db = service.GetService<ISqlSugarClient>();
var isExist = db.DbMaintenance.CreateDatabase();
db.CodeFirst.SetStringDefaultLength(300).InitTables(typeof(TestingRecord));
db.CodeFirst.SetStringDefaultLength(300).InitTables(typeof(DailyRecord));
// 测试插入并检索
//db.Insertable<TestingRecord>(new TestingRecord
//{
// SN = "Null",
// OrderCode = "Null",
// MATNR = "Null",
// TestName = "Null",
// TestTime = DateTime.Now,
// Result = "NG",
// Detail = "Null",
// OriginImgPath = "Null",
// ResultImgPath = "Null",
// MessagePath = "Null"
//}).ExecuteCommandAsync();
//List<TestingRecord> TempData = db.Queryable<TestingRecord>().Where(g => true).ToList();
//Console.WriteLine(TempData);
}
private void ConfigureServices(IServiceCollection services)
{
// 添加 WPF 主窗口
services.AddTransient<MainWindow>();
}
}
}
- 使用
configuration
读取配置信息 - 使用
serviceCollection.AddScoped<ISqlSugarClient>
注入单例 - 使用
InitDatabase
初始化数据库 - 注释的部分是在检测数据库的连接情况
- 在需要使用的视图层,接受注入的单例,然后调用方法来操作数据库
public MainWindow(ISqlSugarClient sqlSugarClient)
{
InitializeComponent();
_sqlSugarClient = sqlSugarClient;
List<TestingRecord> TempData = _sqlSugarClient.Queryable<TestingRecord>().Where(g => true).ToList();
Console.WriteLine(TempData);
- 查询数据库的依据是泛型,同样地,初始化数据库使用的也是泛型。以 TestingRecord 为例:
db.CodeFirst.SetStringDefaultLength(300).InitTables(typeof(TestingRecord));
...
List<TestingRecord> TempData = _sqlSugarClient.Queryable<TestingRecord>().Where(g => true).ToList();
在 Models 中创建一个子目录 Vision 在其中放入 TestingRecord.cs
文件:
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace wpfdemo.Models.Vision
{
public class TestingRecord
{
[Key]
[ScaffoldColumn(false)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
public int ID { get; set; }
public string Werk { get; set; } = "";
public string Factory { get; set; } = "";
public string Line { get; set; } = "";
public string Process { get; set; } = "";
public string User { get; set; } = "";
public string SN { get; set; } = "";
public string OrderCode { get; set; } = "";
public string MATNR { get; set; } = "";
public string TestName { get; set; } = "";
public DateTime TestTime { get; set; }
public string Result { get; set; }
public string Detail { get; set; } = "";
public bool Rejudge { get; set; } = true;
public string OriginImgPath { get; set; } = "";
public string ResultImgPath { get; set; } = "";
public string MessagePath { get; set; } = "";
}
}
- 在需要使用此类型的地方使用
using wpfdemo.Models.Vision;
即可。
11. 在任何地方拿到单例而不通过依赖注入的方式
ISqlSugarClient temp = App.ServiceProvider.GetService<ISqlSugarClient>() as ISqlSugarClient;
List<TestingRecord> TempData = new List<TestingRecord>();
if (temp != null)
{
TempData = temp.Queryable<TestingRecord>().Where(g => true).ToList();
}
Console.WriteLine(TempData);
其中,App 是全局可访问的。