<Grid.RowDefinitions>

</Grid.RowDefinitions>

        <Grid>
<UniformGrid Columns="2">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<InkCanvas Name="ink" Background="Transparent" Cursor="Pen" ForceCursor="True">
<Image Name="ImgShow" Source="/temp.png" IsHitTestVisible="False"> </Image>
</InkCanvas>
</ScrollViewer>
<UniformGrid Rows="2">
<GroupBox Header="Mask" >
<Image x:Name="imgMask"></Image>
</GroupBox>
<GroupBox Header="Result">
<Image x:Name="imgResult"></Image>
</GroupBox>
</UniformGrid>
</UniformGrid> </Grid>
<StackPanel Grid.Row="1" Margin="20">
<DockPanel >
<Grid Grid.Row="1" VerticalAlignment="Center" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" VerticalAlignment="Center" Content="绘制墨迹" Click="RadioButton_Click" IsChecked="True"/>
<RadioButton Grid.Column="1" Content="按点擦除" Click="RadioButton_Click"/>
<RadioButton Grid.Column="2" Content="按线擦除" Click="RadioButton_Click"/>
<RadioButton Grid.Column="3" Content="选中墨迹" Click="RadioButton_Click"/>
<RadioButton Grid.Column="4" Content="停止操作" Click="RadioButton_Click"/>
</Grid>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20 0 0 0">颜色选择:</TextBlock>
<Border CornerRadius="5" x:Name="colorchk" Background="Black" Width="50" HorizontalAlignment="Left" MouseLeftButtonDown="Grid_MouseLeftButtonDown" ></Border> </DockPanel>
<DockPanel>
<Button Margin="20 0 0 0" Width="100" Height="30" Click="Button_Click">Roi截取</Button>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Margin="20 0 0 0">兴趣区域平均值:<Run Foreground="#e03997" Name="txt_meanValue"></Run></TextBlock>
<Slider Value="120" x:Name="threshould_slider" Width="200" TickPlacement="Both" TickFrequency="1" Maximum="255" IsSnapToTickEnabled="True"></Slider>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">阈值<Run Text="{Binding ElementName=threshould_slider,Path=Value}"></Run></TextBlock>
<Button Margin="20 0 0 0" Width="100" HorizontalAlignment="Left" Height="30" Click="floodfill_Click">漫水填充</Button>
</DockPanel>
</StackPanel> </Grid> </Grid>

//cs代码
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Util;
using Color = System.Drawing.Color;
using Point = System.Drawing.Point;
using Rectangle = System.Drawing.Rectangle;

namespace MaskGetMean
{
///

/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
//声明一个 DrawingAttributes 类型的变量
DrawingAttributes drawingAttributes;
///
/// 默认图像路径。可拖拽图像进窗体
///
string imgpath = (AppDomain.CurrentDomain.BaseDirectory + "temp.png");

    public MainWindow()
{
InitializeComponent();
//创建 DrawingAttributes 类的一个实例
drawingAttributes = new DrawingAttributes();
//将 InkCanvas 的 DefaultDrawingAttributes 属性的值赋成创建的 DrawingAttributes 类的对象的引用
//InkCanvas 通过 DefaultDrawingAttributes 属性来获取墨迹的各种设置,该属性的类型为 DrawingAttributes 型
ink.DefaultDrawingAttributes = drawingAttributes;
//设置 DrawingAttributes 的 Color 属性设置颜色 }
/// <summary>
/// 拖拽
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MainWindow_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effects = DragDropEffects.Link; //WinForm中为e.Effect = DragDropEffects.Link
else e.Effects = DragDropEffects.None; //WinFrom中为e.Effect = DragDropEffects.None
} private void MainWindow_Drop(object sender, DragEventArgs e)
{
string fileName = ((System.Array)e.Data.GetData(DataFormats.FileDrop)).GetValue(0).ToString();
if (fileName.EndsWith(".jpg") || fileName.EndsWith(".png") || fileName.EndsWith(".bmp"))
{
imgpath = fileName;
ImgShow.Source = new BitmapImage(new Uri(imgpath)); //The Imageviewer 直接弹出新的窗口
Image<Bgr, byte> loadImg = new Image<Bgr, byte>(imgpath);
ImageViewer viewer = new ImageViewer(loadImg, "Loaded Image");
viewer.Show(); //1.使用HistogramViewer不需要事先拉到设计窗口中,他是弹出窗口,你只需要直接使用便可以
HistogramViewer.Show(loadImg[0], 32); //image[0] 显示Blue,bin = 32
HistogramViewer.Show(loadImg, 32); //显示所有信道
//获得文件名后的操作...
} }
private void Button_Click(object sender, RoutedEventArgs e)
{
//原始图像
var OldImage = CvInvoke.Imread(imgpath);
//获取图像原始大小和显示大小的比例
double a = OldImage.Width / ImgShow.Source.Width;
//获取画的坐标线集合
var list = ink.Strokes;
//装轮廓集合
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint(); //获取画的坐标点集合
foreach (var item in list)
{ //单个轮廓坐标集合
VectorOfPoint vectorOfPoint = new VectorOfPoint();
foreach (var stylusPoint in item.StylusPoints)
{
vectorOfPoint.Push(new System.Drawing.Point[] { new System.Drawing.Point((int)(stylusPoint.X * a), (int)(stylusPoint.Y * a)) });
}
if (vectorOfPoint.Size <= 0)
break;
contours.Push(vectorOfPoint);
}
//准备掩膜图像
Image<Gray, byte> mask = new Image<Gray, byte>(OldImage.Width, OldImage.Height);
//设置全黑
mask.SetZero();
//把轮廓全部绘制成白色在mask上变成感兴趣的区域 类似roi
for (int i = 0; i < contours.Size; i++)
{
CvInvoke.DrawContours(mask, contours, i, new MCvScalar(255, 255, 255), -1, LineType.AntiAlias, null, int.MaxValue);
}
//准备结果图像
Image<Bgr, byte> Result = new Image<Bgr, byte>(OldImage.Width, OldImage.Height);
//显示
imgMask.Source = BitmapToBitmapImage(mask.ToBitmap());
//CvInvoke.Imshow("DrawContours", mask);
//获取感兴趣的区域到结果图
OldImage.CopyTo(Result, mask);
//显示
//CvInvoke.Imshow("mask", Result);
imgResult.Source = BitmapToBitmapImage(Result.ToBitmap());
txt_meanValue.Text = CvInvoke.Mean(Result).V0.ToString();
}
/// <summary>
/// 左键选择画笔颜色
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
System.Windows.Forms.ColorDialog colorDialog = new System.Windows.Forms.ColorDialog();
if (colorDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
System.Drawing.SolidBrush sb = new System.Drawing.SolidBrush(colorDialog.Color);
SolidColorBrush solidColorBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(sb.Color.A, sb.Color.R, sb.Color.G, sb.Color.B));
colorchk.Background = solidColorBrush;
drawingAttributes.Color = new System.Windows.Media.Color() { A = sb.Color.A, B = sb.Color.B, G = sb.Color.G, R = sb.Color.R };
}
} /// <summary>
/// Bitmap转BitmapImage 用于Image控件成像
/// </summary>
/// <param name="bitmap"></param>
/// <returns></returns>
public static BitmapSource BitmapToBitmapImage(System.Drawing.Bitmap bitmap)
{
if (bitmap == null)
return null;
try
{
using (System.Drawing.Bitmap source = bitmap)
{
IntPtr ptr = source.GetHbitmap(); //obtain the Hbitmap BitmapSource bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
ptr,
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); DeleteObject(ptr); //release the HBitmap
return bs;
}
}
catch (Exception)
{ return null;
} }
[DllImport("gdi32")]
private static extern int DeleteObject(IntPtr o);
/// <summary>
/// ink画板事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void RadioButton_Click(object sender, RoutedEventArgs e)
{
if ((sender as RadioButton).Content.ToString() == "绘制墨迹")
{
ink.ForceCursor = true;
ink.EditingMode = InkCanvasEditingMode.Ink;
}
else
{
ink.ForceCursor = false;
if ((sender as RadioButton).Content.ToString() == "按点擦除")
{
ink.EditingMode = InkCanvasEditingMode.EraseByPoint;
} else if ((sender as RadioButton).Content.ToString() == "按线擦除")
{
ink.EditingMode = InkCanvasEditingMode.EraseByStroke;
} else if ((sender as RadioButton).Content.ToString() == "选中墨迹")
{
ink.EditingMode = InkCanvasEditingMode.Select;
} else if ((sender as RadioButton).Content.ToString() == "停止操作")
{
ink.EditingMode = InkCanvasEditingMode.None;
}
} }
/// <summary>
/// 漫水填充
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void floodfill_Click(object sender, RoutedEventArgs e)
{
int threshould = (int)threshould_slider.Value;
var color = System.Drawing.Color.White;
//原始图像
var OldImage = CvInvoke.Imread(imgpath);
//获取图像原始大小和显示大小的比例
double a = OldImage.Width / ImgShow.Source.Width;
//获取画的坐标线集合
var list = ink.Strokes;
//装轮廓集合
VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
//获取画的坐标点集合
foreach (var item in list)
{ //单个轮廓坐标集合
VectorOfPoint vectorOfPoint = new VectorOfPoint();
foreach (var stylusPoint in item.StylusPoints)
{
vectorOfPoint.Push(new System.Drawing.Point[] { new System.Drawing.Point((int)(stylusPoint.X * a), (int)(stylusPoint.Y * a)) });
}
if (vectorOfPoint.Size <= 0)
break;
contours.Push(vectorOfPoint);
}
if (contours.Size == 0) return;
//清空点
ink.Strokes.Clear();
//计算点的阈值平均值(不太好用 也就是没写好) //var GrayOldImage = OldImage.Clone();
//if (GrayOldImage.NumberOfChannels == 3)
// CvInvoke.CvtColor(GrayOldImage, GrayOldImage, ColorConversion.Rgb2Gray);
//int rows = GrayOldImage.Rows, cols = GrayOldImage.Cols, step = GrayOldImage.Step;
//threshould = 0;
//long count = 0;
//for (int i = 0; i < contours.Size; i++)
//{
// for (int j = 0; j < contours[i].Size; j++)
// { // unsafe
// {
// byte* dataptr = (byte*)GrayOldImage.DataPointer;
// ///单通道图像遍历方式
// int index = contours[i][j].X * step + contours[i][j].Y;
// value += dataptr[index];
// }
// }
// count += contours[i].Size;
//}
//value = value / count;
var data = FloodFill(OldImage.ToBitmap(), contours[0][0], color, threshould);
if (data != null)
{
VectorOfVectorOfPoint NewVec = new VectorOfVectorOfPoint();
CvInvoke.FindContours(data.ToImage<Gray, byte>(), NewVec, null, Emgu.CV.CvEnum.RetrType.External, Emgu.CV.CvEnum.ChainApproxMethod.ChainApproxTc89Kcos);
CvInvoke.DrawContours(OldImage, NewVec, 0, new MCvScalar(0, 255, 0), 1, LineType.AntiAlias, null, 1);
//显示
imgMask.Source = BitmapToBitmapImage(OldImage.ToBitmap());
//显示
imgResult.Source = BitmapToBitmapImage(OldImage.ToBitmap());
txt_meanValue.Text = CvInvoke.Mean(OldImage).V0.ToString();
//-----------获取roi---------------
//准备掩膜图像
Image<Gray, byte> mask = new Image<Gray, byte>(OldImage.Width, OldImage.Height);
//设置全黑
mask.SetZero();
//把轮廓全部绘制成白色在mask上变成感兴趣的区域 类似roi
for (int i = 0; i < NewVec.Size; i++)
{
CvInvoke.DrawContours(mask, NewVec, i, new MCvScalar(255, 255, 255), -1, LineType.AntiAlias, null, int.MaxValue);
}
//准备结果图像
Image<Bgr, byte> Result = new Image<Bgr, byte>(OldImage.Width, OldImage.Height); //获取感兴趣的区域到结果图
OldImage.CopyTo(Result, mask);
//显示
//CvInvoke.Imshow("mask", Result);
imgResult.Source = BitmapToBitmapImage(Result.ToBitmap());
} } /// <summary>
///
/// </summary>
/// <param name="src">原图</param>
/// <param name="location">检测点</param>
/// <param name="fillColor">填充颜色</param>
/// <param name="threshould"阈值></param>
/// <returns>填充图,非填充部分为默认值</returns>
unsafe public Bitmap FloodFill(Bitmap src, Point location, Color fillColor, int threshould)
{
try
{
Bitmap srcbmp = src;
Color backColor = srcbmp.GetPixel(location.X, location.Y);
Bitmap dstbmp = new Bitmap(src.Width, src.Height);
int w = srcbmp.Width; int h = srcbmp.Height;
Stack<Point> fillPoints = new Stack<Point>(w * h);
System.Drawing.Imaging.BitmapData bmpData = srcbmp.LockBits(new Rectangle(0, 0, srcbmp.Width, srcbmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
System.Drawing.Imaging.BitmapData dstbmpData = dstbmp.LockBits(new Rectangle(0, 0, dstbmp.Width, dstbmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
int stride = bmpData.Stride; int stridedst = dstbmpData.Stride; byte* srcbuf = (byte*)bmpData.Scan0.ToPointer();
int* dstbuf = (int*)dstbmpData.Scan0.ToPointer();
int cr = backColor.R, cg = backColor.G, cb = backColor.B, ca = backColor.A;
byte fcr = fillColor.R, fcg = fillColor.G, fcb = fillColor.B; int fc = fillColor.ToArgb();
if (location.X < 0 || location.X >= w || location.Y < 0 || location.Y >= h) return null; fillPoints.Push(new Point(location.X, location.Y)); int[,] mask = new int[w, h];
while (fillPoints.Count > 0)
{
Point p = fillPoints.Pop();
mask[p.X, p.Y] = 1;
dstbuf[p.X + p.Y * w] = fc;
if (p.X > 0 && (mask[p.X - 1, p.Y] != 1) && Math.Abs(cb - srcbuf[4 * (p.X - 1) + p.Y * stride]) + Math.Abs(cg - srcbuf[4 * (p.X - 1) + 1 + p.Y * stride]) + Math.Abs(cr - srcbuf[4 * (p.X - 1) + 2 + p.Y * stride]) < threshould && Math.Abs(ca - srcbuf[4 * (p.X - 1) + 3 + p.Y * stride]) < threshould)
{
dstbuf[(p.X - 1) + p.Y * w] = fc;
fillPoints.Push(new Point(p.X - 1, p.Y)); mask[p.X - 1, p.Y] = 1;
}
if (p.X < w - 1 && (mask[p.X + 1, p.Y] != 1) && Math.Abs(cb - srcbuf[4 * (p.X + 1) + p.Y * stride]) + Math.Abs(cg - srcbuf[4 * (p.X + 1) + 1 + p.Y * stride]) + Math.Abs(cr - srcbuf[4 * (p.X + 1) + 2 + p.Y * stride]) < threshould && Math.Abs(ca - srcbuf[4 * (p.X + 1) + 3 + p.Y * stride]) < threshould)
{ dstbuf[(p.X + 1) + p.Y * w] = fc; fillPoints.Push(new Point(p.X + 1, p.Y)); mask[p.X + 1, p.Y] = 1; }
if (p.Y > 0 && (mask[p.X, p.Y - 1] != 1) && Math.Abs(cb - srcbuf[4 * p.X + (p.Y - 1) * stride]) + Math.Abs(cg - srcbuf[4 * p.X + 1 + (p.Y - 1) * stride]) + Math.Abs(cr - srcbuf[4 * p.X + 2 + (p.Y - 1) * stride]) < threshould && Math.Abs(ca - srcbuf[4 * p.X + 3 + (p.Y - 1) * stride]) < threshould)
{ dstbuf[p.X + (p.Y - 1) * w] = fc; fillPoints.Push(new Point(p.X, p.Y - 1)); mask[p.X, p.Y - 1] = 1; }
if (p.Y < h - 1 && (mask[p.X, p.Y + 1] != 1) && Math.Abs(cb - srcbuf[4 * p.X + (p.Y + 1) * stride]) + Math.Abs(cg - srcbuf[4 * p.X + 1 + (p.Y + 1) * stride]) + Math.Abs(cr - srcbuf[4 * p.X + 2 + (p.Y + 1) * stride]) < threshould && Math.Abs(ca - srcbuf[4 * p.X + 3 + (p.Y + 1) * stride]) < threshould)
{ dstbuf[p.X + (p.Y + 1) * w] = fc; fillPoints.Push(new Point(p.X, p.Y + 1)); mask[p.X, p.Y + 1] = 1; }
}
fillPoints.Clear(); srcbmp.UnlockBits(bmpData); dstbmp.UnlockBits(dstbmpData); return dstbmp;
}
catch
{
return null;
}
}
}

}

WPF+Emgucv实现在图像上画出感兴趣的区域 并进行掩膜获取 得到图像均值 和简单的 漫水填充的更多相关文章

  1. Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解

    在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...

  2. 使用JavaScript在Canvas上画出一片星空

    随着Html5的迅猛发展,画布也变得越来越重要.下面我就写一个关于在canvas上画出一片星空的简单的代码的示例. 理论基础 初始化一个canvas,获得一个用于绘制图形的上下文环境context.并 ...

  3. 【wpf】在win10系统上弹出toast和notification

    原文:[wpf]在win10系统上弹出toast和notification 老规矩,先看效果 右下角的notification: 操作中心的notification: 整体效果: 前提条件 1.需要在 ...

  4. Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 图像属性 图像 ...

  5. WPF在圆上画出刻度线

    思路 我们可以使用Ellipse先画出一个圆当背景,然后用Canvas再叠加画上刻度线,就能得到如下的效果 我们先用Ellipse画一个橙色的圆,然后将Canvas的宽度和高度绑定到Ellipse的宽 ...

  6. OpenCV之响应鼠标(四):在图像上绘制出矩形并标出起点的坐标

    涉及到两方面的内容:1. 用鼠标画出矩形.2.在图像上绘制出点的坐标 用鼠标绘制矩形,涉及到鼠标的操作,opencv中有鼠标事件的介绍.需要用到两个函数:回调函数CvMouseCallback和注册回 ...

  7. Android教程:在百度地图上画出轨迹

    [日期:2013-04-14] 来源:Linux社区  作者:crazyxin1988 [字体:大 中 小]     接着上面的项目<Android访问webservice.客户端登录注册> ...

  8. canvas上画出坐标集合,并标记新坐标,背景支持放大缩小拖动功能

    写在前面:项目需求,用户上传一个区位的平面图片,用户可以在图片上添加新的相机位置,并且展示之前已绑定的相机坐标位置,图片支持放大缩小&拖动的功能.新增坐标,页面展示相对canvas定位,保存时 ...

  9. 还没被玩坏的robobrowser(4)——从页面上抓取感兴趣的内容

    背景 本节的知识实际上是属于Beautiful Soup的内容. robobrowser支持Beautiful Soup,一般来说通过下面3个方法获取页面上感兴趣的内容 find find_all s ...

  10. [Java]在窗口界面上画出硬盘中图片文件

    利用类javax.swing.JPanel来在窗口界面上画图.图片文件通过javax.imageio.ImageIO类来获取. import java.awt.Graphics; import jav ...

随机推荐

  1. 【直播回顾】Hello HarmonyOS应用篇第六课——短视频应用开发

    由HDE夏德旺老师主讲的Hello HarmonyOS进阶系列应用篇第六课<短视频应用开发>, 已于6月8日晚上 19 点在HarmonyOS社群内成功举行. 本节课夏德旺老师带领大家了解 ...

  2. 【pytorch学习】之概率

    6 概率 简单地说,机器学习就是做出预测.根据病人的临床病史,我们可能想预测他们在下一年心脏病发作的概率.在飞机喷气发动机的异常检测中,我们想要评估一组发动机读数为正常运行情况的概率有多大.在强化学习 ...

  3. 5月25日,阿里云开源 PolarDB-X 将迎来重磅升级发布

    ​简介:2022年5月25日,阿里云开源 PolarDB-X 将升级发布新版本!PolarDB-X 从 2009 年开始服务于阿里巴巴电商核心系统, 2015 年开始对外提供商业化服务,并于 2021 ...

  4. [GPT] 数据分析工具可以使用机器学习技术来预测未来趋势和提供数据可视化?

      数据分析工具使用机器学习技术来预测未来趋势和提供数据可视化是靠谱的. 机器学习算法可以通过对历史数据的学习来发现数据中的模式和趋势,并利用这些模式和趋势来预测未来的趋势.这种方法已经被广泛应用于许 ...

  5. [Go] Go Module 私有依赖包的管理

    一些自研开发的第三方包,特别是一些业务依赖包,是不允许公开下载的(私有库),并且版本库也可能不支持HTTPS协议, 因此无法使用 go get 或者 go.mod 进行下载和管理,可以通过 GOPRI ...

  6. [FAQ] Phpstorm 代码提示功能失效问题

    如果是之前有代码提示,中间突然不出现提示了,那么考虑重建一下项目索引. 示例: Refer:Phpstorm代码提示 Link:https://www.cnblogs.com/farwish/p/13 ...

  7. [Gin] gin.H{} 与 map[string]interface{}

    gin.H 中的 H 是对 map[string]interface{} 定义的新类型,用来简化生成 map 数据时的书写. // H is a shortcut for map[string]int ...

  8. dotnet 读 WPF 源代码笔记 聊聊 HwndWrapper.GetGCMemMessage 调试消息

    我在阅读 WPF 源代码,在 HwndWrapper 的静态构造函数看到了申请了 HwndWrapper.GetGCMemMessage 这个 Windows 消息,好奇这个消息是什么功能的.通过阅读 ...

  9. WPF 已知问题 某些设备上的应用在 WindowChromeWorker 抛出 System.OverflowException 异常

    准确来说,这个不算是 WPF 的问题,而是系统等的问题.在某些设备上的使用了 WindowChrome 功能的 WPF 应用,将在运行过程,在 WindowChromeWorker 类里面抛出 Sys ...

  10. 2018-8-10-使用-Resharper-快速做适配器

    title author date CreateTime categories 使用 Resharper 快速做适配器 lindexi 2018-08-10 19:16:51 +0800 2018-2 ...