title author date CreateTime categories
WPF 开发
lindexi
2019-8-28 11:3:39 +0800
2018-2-13 17:23:3 +0800
WPF

本文:我遇到的WPF的坑

标记方法被使用

使用 UsedImplicitly 特性可以标记一个没有被引用的方法为反射使用,这时就不会被优化删除。

public class Foo
{[UsedImplicitly]public Foo(){//反射调用}public Foo(string str){//被引用}
}

拼接 URI 路径

我需要将一个 URI 和另一个 URI 拼接如 https://blog.lindexi.com/post/123/api/12 拼接,拿到绝对路径 https://blog.lindexi.com/api/12 可以使用下面方法

var uri1 = new Uri("https://blog.lindexi.com/post/123");
var uri2 = "/api/12";if (Uri.TryCreate(uri1, uri2, out var absoluteUrl)){// 拼接成功,在这里就可以使用 absoluteUrl 拼接后的绝对路径}

单例应用在多实例用户无法使用

如果使用NamedPipeServerStream、Mutex做单实例,需要传入字符串,这时如果传入一个固定的字符串,会在多用户的时候无法使用。

因为如果在一个用户启动的软件,那么就注册了这个字符串,在另一个用户就无法启动。解决方法是传入Environment.UserName

在构造函数传入Environment.UserName有关的字符串就可以在一个用户进行单例,其他用户打开是自己的软件。

public partial class App
{#region Constants and Fields/// <summary>The event mutex name.</summary>private const string UniqueEventName = "{GUID}";/// <summary>The unique mutex name.</summary>private const string UniqueMutexName = "{GUID}"; //这里需要加 Environment.UserName/// <summary>The event wait handle.</summary>private EventWaitHandle eventWaitHandle;/// <summary>The mutex.</summary>private Mutex mutex;#endregion#region Methods/// <summary>The app on startup.</summary>/// <param name="sender">The sender.</param>/// <param name="e">The e.</param>private void AppOnStartup(object sender, StartupEventArgs e){bool isOwned;this.mutex = new Mutex(true, UniqueMutexName, out isOwned);this.eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, UniqueEventName);// So, R# would not give a warning that this variable is not used.GC.KeepAlive(this.mutex);if (isOwned){// Spawn a thread which will be waiting for our eventvar thread = new Thread(() =>{while (this.eventWaitHandle.WaitOne()){Current.Dispatcher.BeginInvoke((Action)(() => ((MainWindow)Current.MainWindow).BringToForeground()));}});// It is important mark it as background otherwise it will prevent app from exiting.thread.IsBackground = true;thread.Start();return;}// Notify other instance so it could bring itself to foreground.this.eventWaitHandle.Set();// Terminate this instance.this.Shutdown();}#endregion
}

当鼠标滑过一个被禁用的元素时,让ToolTip 显示

设置ToolTipService.ShowOnDisabled为 true

<Button ToolTipService.ShowOnDisabled="True">  

获取设备屏幕数量

通过 WinForms 方法获取

System.Windows.Forms.Screen.AllScreens

上面就可以拿到所有的屏幕,通过 Count 方法就可以知道有多少屏幕

var screenCount = Screen.AllScreens.Length;

获取当前域用户

在 WPF 找到当前登陆的用户使用下面代码

using System.Security.Principal;// 其他代码WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();string crentUserAd = windowsIdentity.Name;

输出 crentUserAd 可以看到 设备\\用户 的格式

绑定资源文件里面的资源

在 WPF 的 xaml 可以通过 x:Static 绑定资源,但是要求资源文件里面的对应资源设置访问为公开

如果没有设置那么将会在 xaml 运行的时候提示

System.Windows.Markup.XamlParseException 在 System.Windows.Markup.StaticExtension 上提供值xxx

此时在设计器里面是可以看到绑定成功,只是在运行的时候提示找不到,展开可以看到下面提示

无法将 xx.Properties.Resources.xx  StaticExtension 值解析为枚举、静态字段或静态属性

解决方法是在 Resource.resx 里面的访问权限从 internal 修改为 public 就可以

判断 WPF 程序使用管理员权限运行

引用命名空间,复制下面代码,然后调用 IsAdministrator 方法,如果返回 true 就是使用管理员权限运行

using System.Security.Principal;public static bool IsAdministrator(){WindowsIdentity current = WindowsIdentity.GetCurrent();WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);//WindowsBuiltInRole可以枚举出很多权限,例如系统用户、User、Guest等等return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);}

C# 判断软件是否是管理员权限运行 - 除却猩猩不是猿 - CSDN博客

注册全局事件

如果需要注册一个类型的全局事件,如拿到 TextBox 的全局输入,那么可以使用下面代码

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.KeyDownEvent, new RoutedEventHandler(方法));

高版本的 WPF 引用低版本类库导致无法启动

如果在一个 .net 4.0 的 WPF 程序引用一个 .net 2.0 的库,那么就会让程序无法运行,解决方法添加useLegacyV2RuntimeActivationPolicy

打开 app.config 添加 useLegacyV2RuntimeActivationPolicy="true" 在 startup 元素

下面是 app.config 代码

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

参见:WPF 软件引用其他类库启动无反应问题 - 灰色年华 - CSDN博客

非托管使用托管委托

如果有一个 C++ 写的dll,他需要一个函数指针,在C#使用,就可以传入委托。

那么简单的方法是这样写:

    private static void Func(){}public void C(){c(Func);}

其中c就是C++写的函数,传进去看起来好像正常。

但是有时候程序不知道怎么就炸了。

因为这样写是不对的。

传入的不是函数地址,传入的是把函数隐式转换委托,然后转换的委托是局部变量,会被gc,所以在C++拿到的是一个被回收的委托,调用时就会炸。

这里无法用catch,所以用这个会让程序退出。

调用C#的函数,使用委托,是隐式转换,上面代码可以写成下面的

    private static void Func(){}public void C(){var temp = new delegate(){ Func };c(temp);}

于是在函数完就把temp放到gc在调用时找不到委托。

一个好的做法

    private static void Func(){}private delegate Temp { get; } = new delegate(){Func};private void C(){c(Temp);}

放在静态变量不会gc调用不会空,可以这样不会出现上面问题。

元素失去获得

元素可以使用 CaptureMouse 方法获得,这可以用在拖动,一旦拖动出元素可以获得,得到拖动结束。

但是有时会失去获得,如果自己需要失去,可以使用 Mouse.Capture(null) 但是在没有自己使用的这个函数,失去获得,可以的是:

设置元素可命中false,如果看到元素失去交互,而且堆栈没有任何地方使用失去获得,那么可能就是存在设置元素可命中false。

如果有两个函数同时 获得 一个元素,会不会出现 失去获得?不会,如果同一个元素多次 获得,那么不会出现失去获得。如果这是让另一个获得,那么这个元素就是失去获得。可以通过元素.IsMouseCaptured 判断元素获得。

可以通过 Mouse.Captured 获得现在 Mouse 是否获得。如果返回是 null ,没有获得,但是元素获得存在一些问题,在失去焦点或其他,可能就失去获得。

CaptureMouse/CaptureStylus 可能会失败 - walterlv

反射引用程序集

这是比较难以说明的问题,总之,可能出现的问题就是引用了一个 xaml 使用的资源库,或使用了一个只有反射才访问的库。

原因: 如果在引用一个库,引用代码没有直接使用的程序集。使用的方法就是使用 xaml 或反射来使用。那么在生成,vs 不会把程序集放在输出文件夹。

问题: 反射报错,无法找到程序集。

例子: 如果我用了一个程序集,然而代码没有直接引用,而是反射使用,这样,vs判断这个程序集没有使用,最后把他清除。所以会出现反射无法拿到,而且很难知道这里出现坑。

为了解决 xaml 和反射无法拿到的坑,可以使用 在任意位置使用 Debug.Write(typeof(程序集里的一个类)) 方法让 vs 引用程序集。

那么在 Release 上为何还可以把程序集放在输出文件夹呢?因为我也不知道原因,如果你知道的话,那么请告诉我一下。

使用十进制设置颜色

在 xaml 如果需要使用 十进制设置颜色,请使用下面代码

    <SolidColorBrush x:Key="LikeGreen"><SolidColorBrush.Color><Color R="100" G="200" B="30" A="100"/></SolidColorBrush.Color></SolidColorBrush>

https://stackoverflow.com/a/47952098/6116637

WPF 判断文件是否隐藏

可以设置一些文件是隐藏文件,那么 WPF 如何判断 FileInfo 是隐藏文件?

简单的代码,通过判断 Attributes 就可以得到,请看下面。

    file.Attributes.HasFlag(FileAttributes.Hidden)

触发鼠标事件

触发鼠标点下事件,可以使用下面代码

element.RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, 1){RoutedEvent = Mouse.MouseDownEvent});

TextBlock 换行

使用 就可以换行

win10 uwp 在 xaml 让 TextBlock 换行

在 xaml 绑定索引空格

如果一个索引需要传入空格,那么在 xaml 使用下面代码是无法绑定

{Binding MyCollection[foo bar]}

需要使用下面代码

{Binding MyCollection[[foo&x20;bar]]}

Binding to an index with space in XAML – Ivan Krivyakov

使用 Task ContinueWith 在主线程

在有时候使用 Task 的 Delay 之后想要返回主线程,可以使用 ContinueWith 的方法,请看代码

            Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith(_ => Foo()// 如果 Foo 不需要在主线程,请注释下面一段代码, TaskScheduler.FromCurrentSynchronizationContext());

核心是 TaskScheduler.FromCurrentSynchronizationContext 方法

如果 Foo 不需要在主线程,就可以删除 TaskScheduler.FromCurrentSynchronizationContext 代码

WPF-数据绑定:日期时间格式

{Binding datetime,StringFormat='{}{0:yyyy年MM月dd日 dddd HH:mm:ss}',ConverterCulture=zh-CN}

指定ConverterCulture为zh-CN后星期就显示为中文了。

WPF 第三方DLL 强签名

参见:http://www.cnblogs.com/xjt927/p/5317678.html

WPF 去掉最大化按钮

通过在窗口添加下面代码

ResizeMode="NoResize"

窗口就剩下一个关闭同时用户也无法拖动修改窗口大小

WPF TextBox 全选

在一个按钮点击的时候全选 TextBox 的内容,可以在按钮里面调用 SelectAll 方法

textBox.SelectAll();

上面代码的 textBox 就是界面写的 TextBox 元素

如果发现调用上面的代码 TextBox 没有全选,可能是 TextBox 没有拿到焦点,可以尝试下面代码

textBox.Focus();
textBox.SelectAll();

WPF 获取文本光标宽度

通过 SystemParameters.CaretWidth 获取宽度

var caretWidth = SystemParameters.CaretWidth;

详细请看 SystemParameters.CaretWidth Property

wpf动画——new PropertyPath属性链 - 影天 - 博客园

wpf动画——缓动动画Animation Easing - 影天 - 博客园

2019-8-28-WPF-开发相关推荐

  1. WPF开发的实用小工具 - 快捷悬浮菜单

    WPF开发的实用小工具 - 快捷悬浮菜单 ❝ 本文由网友投稿,Dotnet9站长整理.站长觉得这小工具很实用,站长家里.公司也在尝试使用了. 行文目录: 这工具有什么用? 正文 源码获取及应用下载体验 ...

  2. WPF开发学生信息管理系统【WPF+Prism+MAH+WebApi】(一)

    最近通过WPF开发项目,为了对WPF知识点进行总结,所以利用业余时间,开发一个学生信息管理系统[Student Information Management System].本文主要简述如何通过WPF ...

  3. 使用WPF开发BLE应用

    先上官方文档: 蓝牙 GATT 客户端,文档是关于UWP开发BLE的,WPF如果要使用BLE的API,得手动添加几个引用(可参考这篇文章),该文章说需要添加3个引用,但本人创建的WPF应用默认已经有 ...

  4. Beta冲刺(7/7)——2019.5.28

    所属课程 软件工程1916|W(福州大学) 作业要求 Beta冲刺(7/7)--2019.5.28 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪万里 ...

  5. HighNewTech:2019.08.08鲲鹏开发入门暨 2019华为云鲲鹏开发者大赛参赛攻略

    High&NewTech:2019.08.08鲲鹏开发入门暨 2019华为云鲲鹏开发者大赛参赛攻略 目录 演讲PPT 1.基础知识 2.赛题解读 3.参赛攻略 4.FAQ 演讲PPT 1.基础 ...

  6. [翻译] 构建完美的WPF开发工作站

    原文:http://blogs.msdn.com/tims/archive/2006/12/20/building-a-perfect-wpf-developer-workstation.aspx 作 ...

  7. 用WPF开发Mapxtreme-- 在.net 4.0 下面开发WPF mapxtreme 程序

    前面 <用WPF开发Mapxtreme> 介绍过在.net 3.5下开发Mapxtreme的WPF程序.但是在实际开发过程中用到了DevExpress的控件. 那个Ribbon和DockP ...

  8. [WPF]WPF开发方法论

    纵观Windows GUI应用程序开发方法,从Windows API.MFC到Visual Basic再到.NET Framework,WPF的开发方法论是在.NET Framework方法论的基础上 ...

  9. 46个PPT下载丨QCon 2019年全球软件开发大会PPT

    之前有读者询问一些数据库相关的大会资源,小编收集整理了很多文档,创建了相应的墨天轮专栏,后续将逐个分享到"数据和云"公众号. 这里我们分享2019 PostgreSQL中国技术大会 ...

  10. 2019.11.28

    2019.11.28 % 滑动平均(均值滤波) sliding_window = 5; impulse_fft_tmp = impulse_fft_6k; for i = 1+sliding_wind ...

最新文章

  1. Quartz.net官方开发指南 第五课: SimpleTrigger
  2. python os open_Python中的Oserror:无法打开资源,之,OSErrorcannotopenresource
  3. javascript获取浏览器客户端IP
  4. 深入浅出Java核心技术开篇(总结)
  5. (20)VHDL移位寄存器
  6. C++面向对象高级编程(上) 第一周 侯捷
  7. ExtAspNet发展规划
  8. shared_ptr四宗罪
  9. uestc 方老师的分身 II
  10. 对于长时间装载的ASP.NET页面如何在客户端浏览器中显示进度?
  11. 本机号码一键登录原理与应用
  12. 分享一些查询资源的网站
  13. 骨传导耳机哪个好,骨传导耳机运动品牌推荐
  14. VMWare虚拟机IP变成127.0.0.1怎么办
  15. [英语阅读]《花花公子》十大派对大学出炉
  16. 女生做数据分析师累吗?零基础可以转行吗?
  17. python实现五大基本算法语句_python实现各种最优化算法
  18. router-vue中meta参数
  19. 【洛谷】P3367 【模板】并查集
  20. CF Canada Cup 2016 D 优先队列

热门文章

  1. html5 评测 小米6,小米6X评测:骁龙660中性价比最高的一款手机
  2. 集成框架 -- Timer定时器
  3. 【前端面试题】2021/3/15面试题
  4. 荣耀10x 鸿蒙,荣耀X10对比10XLite区别哪个好 参数配置对比买谁好
  5. 华为荣耀5cvs华为v9play_荣耀V9play和荣耀V9有什么区别?荣耀V9和V9play区别对比评测...
  6. mysql 5.3.9 for mac 忘记密码
  7. 用MFC制作一个图片浏览器
  8. 计算机不能开机是什么原因是什么,电脑无法开机是什么原因
  9. 用catia画钩子_如何用CATIA绘制杯子,来看看吧
  10. android备份能看到什么意思,安卓手机数据备份与恢复软件有哪些?看完你就知道哪个适合你了...