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. cookie,seesion学习

    一,为什么需要cookie和session? 1,Web应用程序是使用HTTP协议传输数据的.然而HTTP协议是无状态的协议.一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的 ...

  2. Centos6安装mysql5.7最新版

    最近因为公司的服务器需要做基线和漏洞扫描,基线方面问题不大,按照报告上的加固建议,选一些权重高的问题处理一下就好了.但是漏洞扫描就比较坑了,扫出来了十几个高危和一百六十多个中危漏洞,不过还好漏洞基本上 ...

  3. Linux软件管理--RPM工具

    目录 Linux软件管理--RPM工具 Rpm基础概述: Rpm包安装管理 Linux软件管理--RPM工具 Rpm基础概述: RPM全称RPM Package Manager缩写,由红帽开发用于软件 ...

  4. react 编写 基于ant.design 页面的参考笔记

    前言 因为我没有系统的学习 react,是边写边通过搜索引擎找相对的问题,看 ant.design的 中文文档 编写的一个单页面, 以下的笔记都是写 gksvideourlr 时记录的. 重新设定表单 ...

  5. OpenCV常用基本处理函数(6)图像梯度

    形态学转换 腐蚀 img = cv2.imread() kernel = np.ones((,),np.uint8) erosion = cv2.erode(img,kernel,iterations ...

  6. Java Thread之start和run方法的区别

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11421515.html start 用start方法来启动线程,真正实现了多线程运行,这时无需等待ru ...

  7. cocos2D-X 显示中文

    { 将所在的cpp文件改为utf-8 无签名格式再编译 //但,治标不治本 }

  8. Delphi 字符串函数SysUtils单元 AnsiSameStr、AnsiSameText、AnsiCompareStr、AnsiCompareText、AnsiCompareFileName、AnsiUpperCase、AnsiLowerCase、AnsiUpperCaseFileName、AnsiLowerCaseFileName、AnsiPos、AnsiQuotedStr

    USES 单元 SysUtils 非 StrUtils AnsiSameStr.AnsiSameText.AnsiCompareStr.AnsiCompareText.AnsiCompareFileN ...

  9. hdu 5860 Death Sequence(递推+脑洞)

    Problem Description You may heard of the Joseph Problem, the story comes from a Jewish historian liv ...

  10. POJ 2387 Til the Cows Come Home (dijkstra模板题)

    Description Bessie is out in the field and wants to get back to the barn to get as much sleep as pos ...