Режим рендеринга программного обеспечения-WPF

у меня есть пользовательский элемент управления WPF, для которого мне нужно заставить рендеринг в RenderMode.SoftwareOnly. Поскольку я использую .NET 3.5, мне пришлось сделать что-то вроде:

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

но это не работает на моем приложении, программа WPF сбой на нескольких машинах и отключение аппаратного ускорения на уровне реестра, кажется, исправить эту проблему.

вышеуказанный код написан в Loaded событие окна. Если я прав,Loaded событие происходит после отображения элементов управления (MSDN). Так имеет ли смысл иметь вышеуказанный код в этом случае? Если нет, то какое событие было бы для него подходящим?

кроме того, будет параметр RenderMode на визуальный влияет это дети? Или мне нужно установить это специально для каждого дочернего элемента?

любая помощь будет здорово!

3 ответов


вот что мы сделали:

    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;
        }
    }

он работал нормально для нас, за исключением... Это нужно сделать для каждого окна. В .NET 3.5 не было возможности сделать настройку вступающей в силу для всего приложения. И есть некоторые окна, которые вы не будете иметь столько контроля над - например, щелкните правой кнопкой мыши "контекстные" окна. Мы обнаружили, что нет хорошего решения для .NET 3.5, кроме параметра реестра.

редактировать

вот логика, которую мы использовали определите, когда следует принудительно выполнить рендеринг программного обеспечения. Это было предложено инженером поддержки Microsoft.

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

в .NET 4 Microsoft добавила настройку для всего приложения, которая отлично работает для нас. Его гораздо лучший вариант, потому что вам не нужно устанавливать его в каждом окне. Вы просто установите его один раз, и это относится ко всем окна.

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

редактировать

новое свойство .NET 4.0 может быть установлено при запуске приложения следующим образом:

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

вы также можете отключить аппаратную визуализацию для всего процесса, поместив следующую строку в обработчик запуска приложения:

RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;

также можно переключаться во время выполнения


событие -проблема
Для отсутствующего источника hwnd попробуйте следующее:

    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);

область действия RenderMode
Насколько мне известно,для каждого окна WPF существует только одно Win32-окно, а все остальное отображается в WPF. Вот почему я думаю, что установка RenderMode проблемы все содержимое в окне визуальных был. Область действия в этом случае является оконной.