2010-04-07 13 views
6

Khi lưu trữ các điều khiển người dùng WPF trong ứng dụng MDF của WinForms, có một vấn đề về vẽ khi bạn có nhiều biểu mẫu chồng lên nhau tạo ra các tạo phẩm trực quan rất khác biệt. Các tạo tác này chủ yếu có thể nhìn thấy sau khi kéo một biểu mẫu con trên một biểu mẫu khác cũng lưu trữ nội dung WPF hoặc bằng cách cho phép các cạnh của biểu mẫu con được cắt bớt bởi cha mẹ MDI chính khi kéo nó xung quanh. Sau khi kéo và thả biểu mẫu con được hoàn thành, các đồ tạo tác nằm chung quanh nhưng tôi thấy rằng thiết lập tập trung vào cửa sổ của ứng dụng khác và sau đó lấy nét lại cửa sổ ứng dụng của nó, nó được vẽ lại và tất cả đều tốt cho đến khi con các biểu mẫu được di chuyển một lần nữa. Vui lòng xem hình ảnh bên dưới minh họa sự cố.Làm thế nào để tránh hiện vật trực quan khi lưu trữ điều khiển người dùng WPF trong một ứng dụng MDF WinForms?

Screenshot of described artifacts

Những tại Microsoft nhấn mạnh rằng WinForms MDI đã là một giải pháp tối ưu cho MDI và không cần phải tái phát minh trong WPF mặc dù tôi thấy khó để tin rằng họ đã cố gắng tạo ra một ứng dụng WPF cách này vì sự thiếu sót rõ ràng.

CẬP NHẬT: Một vài lưu ý bổ sung mà tôi bỏ ra là nếu tôi tạo các Biểu mẫu này mà không đặt MdiParent chúng được tạo dưới dạng biểu mẫu thông thường và sự cố này không xảy ra. Vấn đề này dường như là duy nhất đối với kịch bản MDI của WinForms. Ngoài ra tôi hiện đang chạy trên Windows 7 Enterprise và tôi nhận thức được kết quả có thể khá khác nhau trên Windows XP nhưng tôi đã không thể kiểm tra điều này.

CẬP NHẬT: Tôi đã tìm thấy một số tài nguyên có liên quan khác về vấn đề này mà tôi nghĩ mình nên chia sẻ.

Trả lời

2

Vâng, tôi có thể đã tìm thấy một giải pháp mặc dù nó cảm thấy như một chút của một hack. Có vẻ như nếu bạn gọi phương thức Làm mới trên phụ huynh MDI, thì một biểu mẫu MDI con được di chuyển mà các tạo phẩm đã ghi chú biến mất. Những thứ trực quan xuất hiện một chút lúng túng khi kéo một cửa sổ nhưng nó có vẻ chấp nhận được nhiều hơn ví dụ tôi đã thể hiện trong bài viết gốc của mình.

private void Form1_Move(object sender, EventArgs e) 
{ 
    this.ParentForm.Refresh(); 

    System.Diagnostics.Debug.WriteLine(string.Format("Form Moved to: ({0},{1})", this.Left, this.Top)); 
} 

Tôi đã thử nhiều kết hợp trong bối cảnh đó như làm mới chỉ là cửa sổ con đó đã được di chuyển bằng các phương pháp gọi như Update(), làm mất hiệu lực(), Refresh() và cũng có thể tôi đã thử những phương pháp tương tự trên phụ huynh MDI cũng như Dispatcher.Invoke (DispatcherPriority.Render, ...)InvalidateVisual() về tổ chức kiểm soát WPF của tôi, nhưng không ai trong số những phương pháp khác làm việc chấp nhận cho gọi Làm mới() cụ thể trên M DI cha mẹ.

Tôi nhận ra rằng đây có lẽ không phải là giải pháp tối ưu vì tôi buộc toàn bộ cửa sổ ứng dụng chính phải làm mới mỗi lần cửa sổ con di chuyển vài pixel nhưng hiện tại, giải pháp hợp lý nhất mà tôi thấy công trinh. Nếu bất cứ ai khác có bất kỳ giải pháp thay thế hoặc bất kỳ cải tiến này, tôi sẽ sẵn sàng chấp nhận câu trả lời của bạn để thay thế.

8

Có vẻ như cách giải quyết khác là hoàn nguyên về hiển thị phần mềm thay vì tận dụng khả năng tăng tốc phần cứng.Đây là suggestion by Marco Zhou trên Diễn đàn MSDN.

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
     this.Loaded += delegate 
     { 
      var source = PresentationSource.FromVisual(this); 
      var hwndTarget = source.CompositionTarget as HwndTarget; 
      if (hwndTarget != null) 
      { 
       hwndTarget.RenderMode = RenderMode.SoftwareOnly; 
      } 
     }; 
    } 
} 

Tôi đã thử nghiệm điều này và giải pháp này dường như làm việc rất tốt và cho đến nay là giải pháp duy nhất mà tôi đã tìm thấy để giải quyết vấn đề này trong một kịch bản interop FoxPro đó là rất giống với WinForms một tôi đăng về ban đầu. Bây giờ tôi đang lập kế hoạch sử dụng giải pháp Refresh gốc của MDI cho dự án WinForms nhưng sau đó cho các ứng dụng interop gốc khác của tôi như khi các điều khiển WPF được lưu trữ trong Visual FoxPro, tôi sẽ sử dụng giải pháp này. Đó là trừ khi tất nhiên nếu một giải pháp thanh lịch hơn được phát hiện cho một trong các trường hợp. Ngoài ra, điều quan trọng cần lưu ý là từ những gì tôi biết là hiển thị phần mềm là lựa chọn duy nhất trên các hệ thống XP và bình thường Visual FoxPro nore WinForms thường tận dụng cùng loại tăng tốc phần cứng mà ứng dụng WPF gốc thực hiện trên Vista OS và lên. Vì vậy, bằng cách sử dụng tùy chọn này có thể không được xấu như nó âm thanh khi bạn phải đối phó với interop. Hiện tại tôi không nhận thức được bất kỳ tác dụng phụ liên quan khi sử dụng giải pháp này nhưng nếu có bất kỳ những người sẽ phải được xem xét nghiêm túc.

2

Kiểm tra trình điều khiển video và thử tắt tăng tốc phần cứng. Hầu hết các hiện vật được gây ra bởi trình điều khiển xấu, thẻ video không thành công hoặc không đủ thời gian để hoàn thành quá trình làm mới.

Bước khắc phục sự cố đầu tiên: Cập nhật trình điều khiển video. Rõ ràng, tôi biết.

Tôi gặp sự cố tương tự, kiểm tra cài đặt thẻ video của tôi (Bảng điều khiển NVidia) cho thấy cài đặt chung rất cao khiến khoảng thời gian làm mới dài hơn có thể bị hủy nếu quá lâu. Đặt cài đặt của tôi về mặc định đã giải quyết hầu hết vấn đề. Nhưng tôi cũng chạy các chương trình băm sử dụng GPU mạnh mẽ vì vậy đây có thể là nguyên nhân của vấn đề tạo tác remaing của tôi mà rất hiếm khi bây giờ và chủ yếu cho thấy khuôn mặt xấu xí của nó trong Visual Studio.

Một bước khắc phục sự cố khác mà tôi gặp phải là tắt tăng tốc phần cứng cho WPF, điều này có thể được thực hiện trong 'HKEY_CURRENT_USER/SOFTWARE/Microsoft/Avalon.Graphics' hoặc có thể ứng dụng có thể thực hiện. không bao giờ thiết lập chúng trong một ứng dụng vì nó sẽ vô hiệu hóa cho tất cả các ứng dụng WPF. Tôi không có cài đặt đăng ký này và tôi cũng không thêm nó vì vậy tôi không chắc chắn về thành công với nó, nhưng nhiều người nói rằng điều này giải quyết được vấn đề của họ. Cũng lưu ý một số ứng dụng có sẵn tùy chọn này, hãy thử tắt tùy chọn nếu có.

Một bước khắc phục sự cố khác là đảm bảo thẻ video là cấp lớp phù hợp để hiển thị. Bất kỳ thẻ nào hỗ trợ DX9 hoặc cao hơn phải đủ, nhưng các yếu tố khác có liên quan (như trường hợp của tôi) vì vậy chỉ vì nó nằm trong danh sách không có nghĩa là nó phù hợp với mục đích của bạn.

Cuối cùng, bạn có thể sử dụng Visual Profiler (một phần của Windows SDK), và các công cụ khác, để giúp xác định những gì đang diễn ra chính xác hơn với WPF thiếu hiệu suất liên quan đến khả năng đồ họa.

ghi chú mức Rendering Tier và thông tin Performance WPF ->http://msdn.microsoft.com/en-us/library/vstudio/ms742196(v=vs.90).aspx

Hope this helps một ai đó.

--Ryan Strassburg

0

Sự kiện người dùng hoặc cửa sổ được tải của bạn;

this.WindowState = System.Windows.WindowState.Minimized; 

this.WindowState = System.Windows.WindowState.Normal; 

nó có vẻ là giải pháp tồi. không cần phải đánh đầu vào tường.

Câu tục ngữ Thổ Nhĩ Kỳ cho biết: mã tốt nhất là mã đang chạy :)

Các vấn đề liên quan