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 event
var 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. Alpha冲刺(5/10)——2019.4.28

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

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

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

  3. 彩票历史记录分析工具 -- 通过实例学习wpf开发

    前言 虽然本人对彩票不感兴趣,仍然有不少人对此情有独钟.他们花大量时间精力去分析彩票的历史记录,企图发现规律,为下一次投注做指导,希望“赢的“”概率增大.不管研究历史记录是否有意义,我用软件实现了对彩 ...

  4. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...

  5. Prism+MaterialDesign+EntityFramework Core+Postgresql WPF开发总结 之 中级篇

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要争对C#初学者,巩固C#常用知识点: 中级篇主要争对WPF布局与Mat ...

  6. .net core 和 WPF 开发升讯威在线客服与营销系统:(插曲)一次端口攻击行为的分析与应对

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...

  7. WPF开发快速入门【7】WPF的拖放功能(Drag and Drop)

    概述 本文描述WPF的拖放功能(Drag and Drop). 拖放功能涉及到两个功能,一个就是拖,一个是放.拖放可以发生在两个控件之间,也可以在一个控件自己内部拖放.假设界面上有两个控件,一个Tre ...

  8. 工欲善其事,必先利其器 之 WPF篇: 随着开发轨迹来看高效WPF开发的工具和技巧

    之前一篇<工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)!> 看到很多朋友回复和支持,非常感谢,尤其是一些拍砖的喷油,感谢你们的批评,受益良多. 我第一份工作便是W ...

  9. wpf开发桌面软件记录

    我的开发环境是win7,vs2013,sql2012,用wpf开发了一个很简单的桌面软件,用Installshield制作的安装包,安装包包含了.framework4.5,在自己电脑上测试正常,想着挺 ...

  10. WPF开发时光之痕日记本

       很久没有写东西了,新的一年新的开始吧. 很早就想自己开发一款日记本软件不仅自己使用,也可以让大家免费使用,最主要的是对自己有一个认可,自学WPF以来,感觉不很顺利,WPF的资料相对来说有点少,主 ...

随机推荐

  1. C# .NET 和.NET Framework区别

    一,C#简介 1>C#是一种面向对象的.运行于.NET Framework之上的高级程序设计语言. 2>C# 是一种简洁.类型安全的面向对象的语言,开发人员可以使用它来构建在 .NET F ...

  2. WPF 的二维绘图(二)——几何图形Geometry

    <本文转自同行> 在WPF的DrawingContext对象中,提供了基本的绘制椭圆和矩形的API:DrawEllipse和DrawRectangle.但是,这些是远远不够用的,我们在日常 ...

  3. java的几种定时器

    https://blog.csdn.net/coolwindd/article/details/82804189 1.@Scheduled注解 @Scheduled注解是最简单的方式,只需要启用定时器 ...

  4. SourceTree 这是一个无效源路径/URL的 解决方法

    看网上的教程都解决不了,这是一个大坑,折腾了很久. 如果说你的项目存在,而不是url真的无效,那就是因为你的权限问题. 因为你的sourcetree登过其他账号,在sourceTree设置里面记录了他 ...

  5. C++判断字符是否是元音字母

    写这个随笔的起因很奇怪. 我本来想找找C++有没有内置的函数(类似isalpha(), isdigit(), isalnum()之流)能直接完成这个功能,但是函数没发现,却发现很多博客都是逐个字符判断 ...

  6. python3.x 类似cpp引用指针传参修改

    #同名局部变量调用外部全局变量: num=100def fun(): global num#告诉编译器是全局的num num+=100 print(num)print(fun)print(fun()) ...

  7. Mysql学习笔记(003)-案例讲解基础查询

    案例讲解基础查询 #.下面的语句是否可以执行成功 SELECT last_name, first_name, salary AS sal FROM employees; #.下面的语句是否可以执行成功 ...

  8. 【leetcode】986. Interval List Intersections

    题目如下: Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted ...

  9. UVa 699 The Falling Leaves (树水题)

    Each year, fall in the North Central region is accompanied by the brilliant colors of the leaves on ...

  10. VC连接SQLite3的方法(MFC封装类)

    SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,支持跨平台,操作简单,能够使用很多语言直接创建数据库.官方网站:www.sqlite.org 在VC环境下编写连接SQLite的 ...