chuyển một kích thước được biết đến với thiết bị pixel
Nếu yếu tố hình ảnh của bạn đã được gắn liền với một PresentationSource (ví dụ, nó là một phần của một cửa sổ có thể nhìn thấy trên màn hình), biến đổi được tìm thấy theo cách này :
var source = PresentationSource.FromVisual(element);
Matrix transformToDevice = source.CompositionTarget.TransformToDevice;
Nếu không, sử dụng HwndSource để tạo ra một hWnd tạm thời:
Matrix transformToDevice;
using(var source = new HwndSource(new HwndSourceParameters()))
transformToDevice = source.TransformToDevice;
không e rằng điều này kém hiệu quả hơn việc xây dựng bằng cách sử dụng hWnd của IntPtr.Zero nhưng tôi cho rằng nó đáng tin cậy hơn vì hWnd được tạo bởi HwndSource sẽ được gắn vào cùng một thiết bị hiển thị như một Cửa sổ mới được tạo ra thực tế. Bằng cách đó, nếu các thiết bị hiển thị khác nhau có các DPI khác nhau, bạn chắc chắn sẽ nhận được giá trị DPI phù hợp.
Một khi bạn đã biến đổi, bạn có thể chuyển đổi bất kỳ kích thước từ một kích thước WPF đến một kích thước điểm ảnh:
var pixelSize = (Size)transformToDevice.Transform((Vector)wpfSize);
Chuyển đổi kích thước pixel để nguyên
Nếu bạn muốn chuyển đổi pixel kích thước thành số nguyên, bạn có thể chỉ cần thực hiện:
int pixelWidth = (int)pixelSize.Width;
int pixelHeight = (int)pixelSize.Height;
nhưng giải pháp mạnh mẽ hơn là giải pháp được sử dụng bởi ElementHost:
int pixelWidth = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, pixelSize.Width));
int pixelHeight = (int)Math.Max(int.MinValue, Math.Min(int.MaxValue, pixelSize.Height));
Bắt kích thước mong muốn của một UIElement
Để có được kích thước mong muốn của một UIElement bạn cần phải chắc chắn rằng nó được đo. Trong một số trường hợp nó sẽ tự động được đo, hoặc vì:
- Bạn đo nó đã
- Bạn đo một trong những tổ tiên của nó, hoặc
- Nó là một phần của một PresentationSource (ví dụ như nó là trong một cửa sổ có thể nhìn thấy) và bạn đang thực hiện dưới đây DispatcherPriority.Render để bạn biết đo lường đã xảy ra tự động.
Nếu yếu tố hình ảnh của bạn chưa được đo nào, bạn nên gọi Đo trên điều khiển hoặc một trong những tổ tiên của nó như là thích hợp, đi qua trong kích thước có sẵn (hoặc new Size(double.PositivieInfinity, double.PositiveInfinity)
nếu bạn muốn kích thước nội dung:
element.Measure(availableSize);
Khi đo được thực hiện, tất cả những gì cần thiết là sử dụng ma trận để chuyển đổi DesiredSize:
var pixelSize = (Size)transformToDevice.Transform((Vector)element.DesiredSize);
Đưa nó tất cả cùng nhau
Đây là một phương pháp đơn giản cho thấy làm thế nào để có được kích thước pixel của một phần tử:
public Size GetElementPixelSize(UIElement element)
{
Matrix transformToDevice;
var source = PresentationSource.FromVisual(element);
if(source!=null)
transformToDevice = source.CompositionTarget.TransformToDevice;
else
using(var source = new HwndSource(new HwndSourceParameters()))
transformToDevice = source.CompositionTarget.TransformToDevice;
if(element.DesiredSize == new Size())
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
return (Size)transformToDevice.Transform((Vector)element.DesiredSize);
}
Lưu ý rằng trong mã này tôi gọi Đo chỉ nếu không có DesiredSize có mặt. Điều này cung cấp một phương pháp thuận tiện để làm tất cả mọi thứ nhưng có một số thiếu sót:
- Nó có thể là cha mẹ của phần tử sẽ trôi qua trong một nhỏ availableSize
- Nó không hiệu quả nếu DesiredSize thực tế là zero (nó được remeasured nhiều lần)
- Nó có thể che giấu lỗi trong một cách mà làm cho các ứng dụng để thất bại do thời gian bất ngờ (ví dụ. các mã được gọi tại hoặc cao hơn DispatchPriority.Render)
Vì những lý do này, tôi sẽ nghiêng để bỏ qua cuộc gọi Đo lường trong Nhận ElementPixelSize và chỉ để cho khách hàng làm điều đó.
Đây có phải là những gì bạn đang tìm kiếm không? http://books.google.com/books?id=xEDKq_QlZ18C&lpg=PA7&ots=lxNG6ADXPa&dq=WPF%20pixels%20to%20real%20screen%20pixels&pg=PA7#v=onepage&q=WPF%20pixels%20to%20real%20screen% 20pixels & f = false – Ragepotato
@Ragepotato, đó chỉ là tổng quan về khái niệm - nó không cung cấp mã để chuyển đổi từ WPF thành pixel và không giải thích cách xử lý các điều kiện biên. –