前言
一、值得学习的C#代码
1. yield
List<int> dmeo = Enumerable.Range(0, 10).ToList();
var demo1 = dmeo.FiveList();
var demo2 = dmeo.FiveListYield();
Console.WriteLine("tty");
static class MyClass
{
public static IEnumerable<int> FiveList(this IEnumerable<int> source)
{
List<int> numList = new List<int>();
foreach (int num in source)
if (num > 5) numList.Add(num);
return numList;
}
public static IEnumerable<int> FiveListYield(this List<int> ints)
{
foreach (int item in ints)
if (item > 5) yield return item;
yield break;
}
}
2. is 判断且赋值
var demo = false;
if (demo is bool valuebool)
Debug.WriteLine(valuebool);
3. Enum中Flags
WeekDays wds = WeekDays.Monday | WeekDays.Sunday | WeekDays.Tuesday;
Console.WriteLine( wds);
Console.WriteLine( (int)wds);
Console.WriteLine(wds.HasFlag(WeekDays.Monday));
[Flags]
enum WeekDays
{
Monday = 0x1,
Tuesday = 0x2,
Wednesday = 0x4,
Thursday = 0x8,
Friday = 0x16,
Saturday = 0x32,
Sunday = 0x64
}
# 数据结构:
1. Array/ArrayList/List
内存上连续存储,节约空间,可以索引访问,读取快,增删慢
2. LinkedList/Queue/Stack
非连续存储,存储数据和地址,只能顺序查找,读取慢,增删快
3. HashSet/SortedSet
纯粹的集合,容器,唯一,无序
4. Hashtable/Dictionary/SortedDictionary/SortedList
读取,增删都快,key-value,一段连续有限空间放value,基于key散列计算得到地址索引,读取增删都快,开辟的空间比用到的多,hash是用空间换性能
5. C#中为什么字典的查询速度比List快
List实际上是顺序存储的,由于存储结构是顺序的,所以查询起来就很费劲. 但是字典这种数据类型是为了查询做了专门的优化,目的在于快速查找. 所以效率要比List高很多
算法的种类:
排序算法,搜索算法(枚举),图算法,动态规划,贪心,字符串算法,分治,递归,穷举法
# epplus 包 笔记
//获得有数据的区域
var lastAddress = worksheet.Dimension.Address;
//获得有数据的区域最上且最左的单元格
var startCell = worksheet.Dimension.Start.Address;
//获得有数据的区域最下且最右的单元格
var endCell = worksheet.Dimension.End.Address;
Array.Fill 设置默认值
var listarray=new List<int>[10];
Array.Fill<List<int>>(listarray, new List<int> {0});
Random.Shared.Next(10, 38)//随机数
string substring = input[1..^1]; // 从索引 1 开始,到倒数第二个字符结束
// 使用 this 关键字串联构造函数先执行 Test(),后执行 Test(string text)
Test test = new Test("测试数据");
public class Test
{
public Test(){ Console.WriteLine("无参构造函数");}
public Test(string text) : this()
{Console.WriteLine(text+"实例构造函数");}
}
//goto 控制程序跳转到指定的位置执行
提示:goto 语句并不限于在循环中使用,其它的情况也可以使用。但是,goto 语句不能从循环外跳转到循环语句中,而且不能跳出类的范围。
login:
Console.WriteLine("请输入密码");var userpwd = Console.ReadLine();
goto login;
//编码技巧 --- 谨防闭包陷阱 https://niuery.com/post/60
因为编译器会为匿名函数生成一个类(或结构)
var actions = new List<Action>();
for (int i = 0; i < 3; i++)
{
int temp = i; // 创建临时变量并赋值
actions.Add(() => Console.WriteLine(temp));
}
foreach (var action in actions)
{
action(); // 输出结果为 0,1,2
}
//operator implicit 是C#中的一种特殊运算符,用于定义隐式类型转换。隐式类型转换运算符允许将一个类型自动转换为另一个类型,而无需显式地进行类型转换操作。
隐式类型转换运算符有以下特点:
定义为静态方法。
必须定义在源类型(要转换的类型)或目标类型中的一个类型中。
运算符函数的名称必须为 op_Implicit。
必须有一个参数,表示要转换的类型。
必须有一个返回类型,表示转换后的类型。
以下是定义隐式类型转换运算符的一般语法:
public static implicit operator <目标类型>(<源类型> value)
{
// 转换逻辑
// 返回目标类型的值
}
Distance distance = new Distance(1000);
int meters = distance; // 隐式类型转换
Console.WriteLine(meters); // 输出结果为 1000
public class Distance
{
public int Meters { get; }
public Distance(int meters) => Meters = meters;
public static implicit operator int(Distance distance)=>distance.Meters;
}
Distance distance = new Distance(5000);
double kilometers = (double)distance; // 显式类型转换
Console.WriteLine(kilometers); // 输出结果为 5
public class Distance
{
public int Meters { get; }
public Distance(int meters) => Meters = meters;
public static explicit operator double(Distance distance) => distance.Meters / 1000.0;
}
//索引器
public class MyCollection
{
private string[] items = new string[5];
public string this[int index]
{
get => items[index];
set => items[index] = value;
}
}
// 使用索引器
var collection = new MyCollection();
collection[0] = "Item 1";
string item = collection[0];
二、Wpf 代码参考
1. WPF中窗体在同一个位置实现不同页面切换
<Grid>
<ContentControl x:Name="Page_Change" HorizontalAlignment="Left" Margin="127,20,0,0" VerticalAlignment="Top" Height="248" Width="511"/>
</Grid>
Page_Change.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
2. WPF 使用Command,CommandParameter向 MVVM传递多个参数
https://blog.csdn.net/chulijun3107/article/details/119303580
<Binding ElementName="dataPickerInts" Path="Datas"/>
<Binding ElementName="dataPickerInts" />
<Binding Path="Datas" />
3. WPF获取当前用户控件的父级窗体
Window targetWindow = Window.GetWindow(button);
Window mainwin = Application.Current.MainWindow;
4. 消息发送mvvm
Messenger.Default.Register<NotificationMessage>(this, "token", (msg) => Console.WriteLine(msg.Notification));
Messenger.Default.Send(new NotificationMessage("message"), "token");
5. 从App.config中读取链接字符串
<connectionStrings>
<add name="ConnectionString" connectionString="Data Source=.\DbManager\UavImgDesDb.db; " />
</connectionStrings>
ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
6. 查找子控件
foreach (var stepBar in panel.Children.OfType<StepBar>())
stepBar.Prev();
https://github.com/microsoft/WPF-Samples
https://blog.csdn.net/joyyi9/article/details/126131934?spm=1001.2014.3001.5502//zhouyiBLog
Uri uri = new Uri("pack://application:,,,/ResourceFile.xaml", UriKind.Absolute)//url
<Button Content="ClickMe" Click="OnClick1" ClickMode="Hover"/>//按钮模式悬浮
布局、控件、样式、依赖属性、资源、触发器、模板、数据绑定mvvm command//主要知识点
(prism ,MVVMLight ,CommunityToolkit.Mvvm,Microsoft.Toolkit.Mvvm ,Caliburn.Micro(简称CM)) --fody //MVVM开发模式框架
StackPanel,WrapPanel,DockPanel,Grid,UniformGrid,Canvas//六大布局:
Trigger 、MultiTrigger、DataTrigger、 MultiDataTrigger、 EventTrigger //五大触发器:
Default、OneTime、OneWay、TwoWay、OneWayToSource//五种绑定:
BorderBrush="{x:Null}"//18. 设置为空
1.资源 获取, 字典,
<SolidColorBrush x:Key="solidColor" Color="Red"/>
this.Resources["solidColor"]=new SolidColorBrush(Colors.Yellow);
lbResult.Items.Add(pnlMain.FindResource("strPanel").ToString());
lbResult.Items.Add(this.FindResource("strWindow").ToString());
lbResult.Items.Add(Application.Current.FindResource("strApp").ToString());
我们储存了三个不同的「Hello, world!」讯息:一个在App.xaml中、另一个在视窗内、而最后一个是主面板的区域资源。
//设置资源字典
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ButtonExRe.xaml.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
//图片等资源要设置为资源
<local:MyValueConvertor x:Key="FontSizeConvertor"/>//转换器的引用
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
<x:Array x:Key="ComboBoxItems" Type="sys:String">
<sys:String>Item #1</sys:String>
<sys:String>Item #2</sys:String>
<sys:String>Item #3</sys:String>
</x:Array>
2. 一个竖线
<Line Height="15" Y2="1" Stroke="#707070" Stretch="Uniform" Margin="6 0" />
<Rectangle Grid.Column="1" Width="1" Fill="#eeeeee" />
3. 后台代码更改字体或者背景颜色
new SolidColorBrush( Color.FromArgb(255, 255, 0, 0));
new SolidColorBrush((Color)ColorConverter.ConvertFromString("#92e492"));
new SolidColorBrush(Color.FromRgb(255,255,255));
Brushes.Green;
4. 设置回车 设置ESC
<Button Name="btnDefault" IsDefault="true" Click="OnClickDefault">OK</Button>设置回车
<Button Name="btnDefault" IsCancel="true" Click="OnClickDefault">OK</Button>设置ESC
5. mvvm 命令 其他事件
Nuget包:Microsoft.Xaml.Interactions
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding Btncommand}" CommandParameter="read" />
</i:EventTrigger>
</i:Interaction.Triggers>
6. 打开外部链接
Process.Start("www.baidu.com");
7. WPF使用阿里巴巴iconfont矢量图标库
http://t.zoukankan.com/Stay627-p-14469662.html
8. 转换器
https://www.cnblogs.com/yaosj/p/11239116.html
9. 代码添加相同的控件事件
//当同一个UI中存在多个相同控件的相同事件时可考虑使用,例如计算器中的Button事件
this.GridRoot.AddHandler(Button.ClickEvent, new RoutedEventHandler(this.ButtonClicked));
10. 定义访问键
<Button Content="_New"></Button>Alt键+N
11. WPF组件查找
https://www.psvmc.cn/article/2022-10-03-wpf-view-finder.html
12. WPF窗口置顶
https://www.psvmc.cn/article/2022-04-15-wpf-topmost.html
13.WPF只运行一个实例
https://www.psvmc.cn/article/2022-03-11-wpf-instance-one.html
https://www.cnblogs.com/YYkun/p/11459585.html
14. 好看UI推荐
http://dlgcy.com/wpf-control-ui-collection/
15.WPF(C#)获取本机IP
https://www.psvmc.cn/article/2021-07-16-wpf-ip.html
16. 可拖动:
private void Window_MouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)=>
DragMove();
17. 文本换行:
this.TextBlock1.Text = "AAAAAAA\nBBBBBBBB";
<TextBlock Text="AAAAAAA
BBBBBB" />
<TextBlock Width="60" TextWrapping="Wrap" Text="AAAAAAA BBBBBB"/>//自动换行
18.自定义控件:
https://www.cnblogs.com/xiaomingg/tag/WPF/
流程:右键-添加-新建项-自定义控件 =>添加依赖属性=>设置样式=>引用控件
//Microsoft.Xaml.Behaviors.Wpf 事件包
19.事件:
pnlMainGrid.MouseUp += new MouseButtonEventHandler(pnlMainGrid_MouseUp);
20.我们所做的就是去订阅Startup事件,替换StartupUri属性。
private void Application_Startup(object sender, StartupEventArgs e)
{
MainWindow wnd = new MainWindow();wnd.Show();
}
24. WPF整理-Mutex确保Application单例运行
https://www.cnblogs.com/DebugLZQ/p/3160919.html
111.定时器的使用
https://www.cnblogs.com/YYkun/p/9964179.html
21. 程序的异常处理:
DispatcherUnhandledException="Application_DispatcherUnhandledException"
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;//停止程序
}
22. C# wpf 附加属性实现任意控件拖动调整大小
https://blog.csdn.net/u013113678/article/details/121719278
111,Visibility
Visible:元素可见,并参与布局;Collapsed:元素不可见并且不参与布局;Hidden:元素不可见但是参与布局
112. Content Alignment
Control元素还可以通过设置HorizontalContentAlignment和VerticalContentAlignment控制自己的内容元素怎样对齐
113.变换(Transform)
RenderTransform
RotateTransform(Angle(旋转角度)、CenterX和CenterY(旋转中心点))
ScaleTransform
控制变换的属性:ScaleX(水平方向的缩放因子)、ScaleY(垂直方向的缩放因子)、CenterX和CenterY(缩放的中心点)
SkewTransform
控制变换的属性:AngleX(水平倾斜的角度)、AngleY(垂直倾斜的角度)、CenterX和CenterY(倾斜的中心点)
TranslateTransform
控制变换的属性:X(水平偏移量)、Y(垂直偏移量);与上面三种变换不同的是,TranslateTransform作为LayoutTransform应用时不起作用
TransformGroup
可以组合多个变换
---------------------------------------------------------------------------------------------
22. 用户控件 属性和事件
xmlns:uc="clr-namespace:WpfTutorialSamples.User_Controls"
<uc:LimitedInputUserControl Title="Enter title:" MaxLength="30" Height="50" />
<Button Width="100" Height="50" Content="{Binding Value, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, UpdateSourceTrigger=PropertyChanged}" Click="Button_Click" />
<TextBlock Background="{Binding ElementName=myTextUC, Path=Color,Converter={StaticResource ColorToBrushConverter}}" Text="{Binding ElementName=myTextUC, Path=Text}"/>
<local:MyUserControl x:Name="ucNumericUpDown" Width="300" Height="60" Value="0" ValueChanged="ucNumericUpDown_ValueChanged"/>
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(String), typeof(MyUserControl));
public String Value
{
get { return (String)GetValue(ValueProperty); }
set { SetValue(ValueProperty, Value); }
}
private void Input_TextChanged(object sender, TextChangedEventArgs e)
{
RaiseEvent(new RoutedEventArgs(ValueChangedEvent, this));
}
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyUserControl));
public event RoutedEventHandler ValueChanged
{
add { AddHandler(ValueChangedEvent, value); }
remove { RemoveHandler(ValueChangedEvent, value); }
}
23. 用户控件的 附加属性:附加属性都是元素放进去后才会有附加效果
//propa tab Canvas.Left/Canvas.Top
public static double GetWeather(DependencyObject obj)=> (double)obj.GetValue(WeatherProperty);
public static void SetWeather(DependencyObject obj, double value) => obj.SetValue(WeatherProperty, value);
public static readonly DependencyProperty WeatherProperty =
DependencyProperty.RegisterAttached("Weather", typeof(double), typeof(Attach), new PropertyMetadata(0.0, (o, e) =>
{
var element = o as UIElement;
if (element != null)
{
element.RenderTransformOrigin = new Point(0.5, 0.5);
element.RenderTransform = new RotateTransform((double)e.NewValue);
}
}));
<local:TestUserControl Value="111111111" ValueChanged="TestUserControl_ValueChanged"/>
<Button Content="1111111" local:Attach.Weather="60"/>
25. 动画参考:
//GridMain实际为xmal中 Grid窗体的 Name="GridMain"
System.Windows.Media.Animation.Storyboard sb = new System.Windows.Media.Animation.Storyboard();
System.Windows.Media.Animation.ThicknessAnimation dmargin = new System.Windows.Media.Animation.ThicknessAnimation();
dmargin.Duration = new TimeSpan(0, 0, 0, 0, 300);
dmargin.From = new Thickness(0, 300, 0, 300);
dmargin.To = new Thickness(0, 0, 0, 0);
System.Windows.Media.Animation.Storyboard.SetTarget(dmargin, GridMain);
System.Windows.Media.Animation.Storyboard.SetTargetProperty(dmargin, new PropertyPath("Margin", new object[] { }));
sb.Children.Add(dmargin);
sb.Begin();
//关闭部分动画的收缩代码
System.Windows.Media.Animation.ThicknessAnimation dmargin = new System.Windows.Media.Animation.ThicknessAnimation();
dmargin.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300));
dmargin.From = GridMain.Margin;
dmargin.To = new Thickness(0, 300, 0, 300);
System.Windows.Media.Animation.Storyboard.SetTarget(dmargin, GridMain);
System.Windows.Media.Animation.Storyboard.SetTargetProperty(dmargin, new PropertyPath("Margin", new object[] { }));
sb.Children.Add(dmargin);
// 前台XAML代码的实现方式
<Window.Resources>
<Storyboard x:Key="Loading">
<ThicknessAnimation Duration="0:0:0.3" To="0" From="0,300,0,300"
Storyboard.TargetName="GridMain" Storyboard.TargetProperty="Margin" />
</Storyboard>
<Storyboard x:Key="Closing">
<ThicknessAnimation FillBehavior="Stop" Duration="0:0:0.6" To="0,300,0,300" From="0" Storyboard.TargetName="GridMain"
Storyboard.TargetProperty="Margin" Completed="Sb_Completed"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Loaded" >
<BeginStoryboard Storyboard="{StaticResource Loading}"/>
</EventTrigger>
<EventTrigger RoutedEvent="TextBlock.MouseLeftButtonDown">
<BeginStoryboard Storyboard="{StaticResource Closing}" />
</EventTrigger>
</Window.Triggers>
1. binding(绑定源、绑定模式【default、OneWay、TwoWay、OntTime、OneWayToSource】、触发绑定更新的事件【Default、Explicit(手动BindingExpression.UpdayeSource())、PropertyChange、LostFocus】、优先级PriorityBinding)
2. 资源Resources,StaticResource/DynamicResource,静态资源在引用对象初始化时一次性设置完毕;对于动态资源、如果发生了改变则会重新应用资源
3. 总共有三大模板 ControlTemplate,ItemsPanelTemplate,DataTemplate。
主要用途是更改控件的外观。多用于多个内容控件的目标。
主要用于数据的呈现。也被称为显示绑定数据对象的模板。datagrid(添加一些增删查改的按钮或图片的都可)
4. 解释一下ResourceDictionary ?一个哈希表/字典实现 有利于项目中资源共享。
5. 路由事件的哪三种方式/策略(冒泡 直接 隧道)?
6. WPF中的Visibility.Collapsed和Visibility.Hidden有什么区别?
Visibility.Hidden 隐藏控件,但保留它在布局中占用的空间。 所以它呈现空白而不是控件。
Visibilty.Collapsed 不呈现控件并且不保留空格。 控件占用的空间是“折叠的”
7.相对于Winform,WPF有什么优势?
1 - 绑定(更简约的编码)2 - 灵活的外观和感受(资源和样式)3 - 声明式编程 (XAML) 耦合性更低4 - 表现层混合动画(动画开发简单)5 - 快速加载(硬件加速)6- 图形硬件无关(分辨率无关)
8.什么是WPF的值转换器?
值转换器充当目标和源之间的桥梁,当目标与一个源绑定数据类型不一致时,需要值转换器来做中转。
例如有一个文本框和一个按钮控件, 当文本框的文本被填充或为空时,希望启用或禁用按钮控件。
在这种情况下,需要将字符串数据转换为布尔值。这可以使用值转换器实现。
要实现值转换器,需要继承System.Windows.Data命名空间中的IValueConverter,并实现两个方法Convert和ConvertBack。
9. 如何在WPF应用程序中全局捕获异常?
使用“Application.DispatcherUnhandledException”事件。
10. WPF中Dispatcher对象的用途是什么?
几乎每个 WPF 元素都具有线程关联性。
Dispatcher 类用于在他的附加线程上执行工作。 它有一个工作项队列,负责在调度程序线程上执行工作项。
Dispatcher / Thread 关系是一对一的,即一个 Dispatcher 总是与一个线程相关联,可用于将执行分派到该线程。
11.wpf附加属性
附加属性是特殊的依赖属性
用于非定义该属性的类 例如Grid面板的RowDefinition、ColumnDefinition
Canvas面板的Left、Right
DockPanel面板的Dock都是附加属性。
11. 属性触发器
<TextBlock Text="Hello, styled world!" FontSize="28" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
12. 数据触发器
<CheckBox Name="cbSample" Content="Hello, world?" />
<TextBlock HorizontalAlignment="Center" Margin="0,20,0,0" FontSize="48">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="No" />
<Setter Property="Foreground" Value="Red" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=cbSample, Path=IsChecked}" Value="True">
<Setter Property="Text" Value="Yes!" />
<Setter Property="Foreground" Value="Green" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
13.事件触发器
<TextBlock Name="lblStyled" Text="Hello, styled world!" FontSize="18" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.300" Storyboard.TargetProperty="FontSize" To="28" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.800" Storyboard.TargetProperty="FontSize" To="18" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
______________________________________________________________________________________
MVVM框架:
//CommunityToolkit.Mvvm:
public class UserVM : ObservableObject
--属性
[ObservableProperty]
private string newValue = "tianqi";
private int age;
public int Age
{
get => age;
set => SetProperty(ref age, value);
}
Task.Run(() =>
{
while (true)
{
userVM.Age += 1;
Thread.Sleep(1000);
}
});
<TextBlock FontSize="30" Text="{Binding Age}" />
--命令
RelayCommand
AsyncRelayCommand
public RelayCommand ClickCommand => new RelayCommand(() =>
{
MessageBox.Show("test");
});
--消息机制
public class ZMessage
{
public int Code { get; set; }
public string Message { get; set; }
public ZMessage(int code, string msg)
{
Code = code;
Message = msg;
}
}
WeakReferenceMessenger.Default.Register<ZMessage>(
this,
(r, m) =>
{
Console.WriteLine("接收到信息:" + m.Message);
}
);
WeakReferenceMessenger.Default.Send(new ZMessage(100, "Hello"));
public class UserVM : ObservableRecipient, IRecipient<ZMessage>
IsActive = true;
public void Receive(ZMessage message)
{
Name = message.Message;
Age = message.Code;
}
--控制反转
Microsoft.Extensions.DependencyInjection
public interface IUserService
{
string getUserName();
}
public class UserService : IUserService
{
public string getUserName()
{
return "XiaoMing";
}
}
public partial class App : Application
{
public App()
{
Services = ConfigureServices();
this.InitializeComponent();
}
public new static App Current => (App)Application.Current;
public IServiceProvider Services { get; }
private static IServiceProvider ConfigureServices()
{
var services = new ServiceCollection();
services.AddSingleton<IUserService, UserService>();
// ViewModels
services.AddTransient<UserVM>();
return services.BuildServiceProvider();
}
}
private UserVM userVM = (UserVM)App.Current.Services.GetService(typeof(UserVM));
private IUserService userService = (IUserService)App.Current.Services.GetService(typeof(IUserService));
# 代码:
//延迟执行
public static void delay(int milliseconds, Dispatcher dispatcher, Action act)
{
Task.Run(() =>
{
Thread.Sleep(milliseconds);
dispatcher.Invoke(act);
});
delay(
3000,
Dispatcher,
() =>
{
tip_outer.Visibility = Visibility.Hidden;
}
//线程切换
private async Task myFunc()
{
MyApp.Myloading.Show();
await Task.Run(
() =>
{
// 分线程耗时操作
Thread.Sleep(1000);
}
);
MyApp.Myloading.Hide();
}
);
三、WinFom 代码参考
1. c#winform线程间操作UI的五种方法
https://www.cnblogs.com/weifeng123/p/13734999.html
遇到过的bug
- 【SQLite】SQL logic error no such table: xxx
此问题原因是 sqlite数据库链接串写的数据源文件路径不对(可能写了相对路径,系统找不到,或者写了绝对路径,但是路径写错了
都会导致这个报错信息
简单排查方法就是先写死数据库文件所在的路径,然后再运行看效果
错误的写法:"SQLiteConnectionString":"data source=mms.db"
可尝试: "SQLiteConnectionString": "data source=d:\xxx\xxx\xxx\xxx\mms.db"