2011-02-09 9 views
9

Tôi có một điều khiển người dùng WPF mà tôi cần bắt buộc hiển thị trong RenderMode.SoftwareOnly. Kể từ khi tôi đang sử dụng .NET 3.5, tôi đã phải làm một cái gì đó như thế nào,Chế độ hiển thị phần mềm - WPF

var hwndSource = PresentationSource.FromVisual(this) as HwndSource; 
if (hwndSource != null) 
{ 
    hwndSource.CompositionTarget.RenderMode = RenderMode.SoftwareOnly;   
} 

Nhưng điều này không làm việc trên ứng dụng của tôi, Chương trình WPF bị rơi trên vài máy và tắt tăng tốc phần cứng ở mức registry dường để khắc phục vấn đề.

Mã trên được viết trong sự kiện Loaded của cửa sổ. Nếu tôi chính xác, Loaded sự kiện sẽ xảy ra sau khi các điều khiển được hiển thị (MSDN). Vì vậy, nó có ý nghĩa để có mã trên trong sự kiện đó? Nếu không, sự kiện nào sẽ phù hợp với nó?

Ngoài ra, sẽ đặt RenderMode về hình ảnh có ảnh hưởng đến trẻ em không? Hay tôi có cần thiết lập đặc biệt này cho từng yếu tố con không?

Mọi trợ giúp sẽ tuyệt vời!

+0

Hi, tôi tò mò. Giải pháp điều phối đã giúp bạn? – HCL

Trả lời

16

Đây là những gì chúng tôi đã làm:

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     if (ForceSoftwareRendering) 
     { 
      HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource; 
      HwndTarget hwndTarget = hwndSource.CompositionTarget; 
      hwndTarget.RenderMode = RenderMode.SoftwareOnly; 
     } 
    } 

Nó làm việc OK cho chúng ta, TRỪ ... này cần phải được thực hiện cho tất cả các cửa sổ. Trong .NET 3.5 không có cách nào để thiết lập có hiệu lực trong toàn bộ ứng dụng. Và có một số cửa sổ mà bạn sẽ không có nhiều quyền kiểm soát hơn - ví dụ: nhấp chuột phải vào cửa sổ "ngữ cảnh". Chúng tôi thấy rằng không có giải pháp tốt cho .NET 3.5 ngoại trừ cài đặt đăng ký.

Edited

Dưới đây là logic, chúng tôi sử dụng để xác định khi nào để buộc vẽ phần mềm. Nó được đề xuất bởi một kỹ sư hỗ trợ của Microsoft.

public bool ForceSoftwareRendering 
{ 
    get 
    { 
     int renderingTier = (System.Windows.Media.RenderCapability.Tier >> 16); 
     return renderingTier == 0; 
    } 
} 

Trong .NET 4 Microsoft đã thêm cài đặt ứng dụng hoạt động hoàn hảo cho chúng tôi. Đó là một lựa chọn tốt hơn nhiều bởi vì bạn không cần phải đặt nó trên mỗi cửa sổ. Bạn chỉ cần đặt nó một lần và nó áp dụng cho tất cả các cửa sổ.

http://msdn.microsoft.com/en-us/library/system.windows.media.renderoptions.processrendermode(VS.100).aspx

sửa

mới NET 4.0 sở hữu có thể được thiết lập lúc khởi động ứng dụng như thế này:

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     if (ForceSoftwareRendering) 
      RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; 
    } 
} 
+0

"ForceSoftwareRendering" đến từ đâu? Bạn có tìm cách phát hiện máy nào sẽ gặp sự cố khi hiển thị phần mềm không? –

+0

@EduardoWada Tôi sẽ cập nhật câu trả lời để bao gồm điều này. –

+0

có ai biết điều gì đó giống nhau nhưng đối với WinForms không? – user1722669

2

kiện -problem
Đối với thiếu hwnd- nguồn, hãy thử như sau:

Dispatcher.BeginInvoke(new Action(delegate {    
     HwndSource hwndSource = PresentationSource.FromVisual(this) as System.Windows.Interop.HwndSource; 
      if (null == hwndSource) { 
       throw new InvalidOperationException("No HWND"); 
      } 
      HwndTarget hwndTarget = hwndSource.CompositionTarget; 
      hwndTarget.RenderMode = RenderMode.SoftwareOnly; 

    }),System.Windows.Threading.DispatcherPriority.ContextIdle, null); 

phạm vi RenderMode
Theo như tôi biết, chỉ có một Win32 cửa sổ cho mỗi cửa sổ WPF và tất cả các phần còn lại được trả lại tự nhiên trong WPF. Đó là lý do tại sao tôi nghĩ rằng thiết lập RenderMode liên quan đến tất cả nội dung trong cửa sổ mà hình ảnh đang ở. Phạm vi trong trường hợp này là toàn cửa sổ.

+0

cảm ơn. bạn có thể giải thích tại sao Dispatcher được yêu cầu trong trường hợp này? –

+0

@appu: Không bắt buộc - Nhưng nếu hwnd không có mặt tại thời gian thực thi của sự kiện được nạp (nếu đây là vấn đề), thì chờ một cách rõ ràng cho đến khi hệ thống hoàn tất mọi nhiệm vụ quan trọng (chẳng hạn như render :) có thể giúp. Tôi đã thấy rất nhiều kịch bản không phổ biến với các vấn đề có thể được giải quyết theo cách này. Nhưng nó chỉ là một ý tưởng, tôi không thể đảm bảo rằng nó hoạt động. Nhân tiện, tôi sử dụng mã ở trên mà không có người điều phối và không có vấn đề gì cho đến bây giờ. Nhưng tôi chỉ sử dụng nó trong một ứng dụng và ở đó nó là một lựa chọn hiếm khi được sử dụng. Do đó tuyên bố này chắc chắn không phải là đại diện. – HCL

15

Bạn cũng có thể vô hiệu hóa render phần cứng cho toàn bộ quá trình bằng cách đặt dòng tiếp theo trong xử lý ứng dụng khởi động:

RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly; 

Nó cũng có thể chuyển đổi trong thời gian chạy

+2

+1 để có thể chuyển đổi trong thời gian chạy. Đây không phải là ngay lập tức rõ ràng từ MSDN nhưng nó là thông tin quan trọng. – Charlie

+1

.Net 4.0 trở lên –