2009-06-01 6 views
2

В настоящее время у меня есть приложение Winforms, которое использует прозрачные эффекты. Однако это является абсолютной болью в преподобном сзади! Winforms, поскольку Im обучение не имеет дело с прозрачностью особенно хорошо.C# Winforms-WPF interop

Мне было интересно, будет ли это проще с использованием компонентов WPF для бит прозрачности и winforms для остальных (обратите внимание, хотя Id Id, чтобы переместить все приложение в WPF, это просто невозможно). Я почти ничего не знаю о WPF, поэтому причина здесь! То, что я рассматривал, было:

1) Принимать компонент WPF в пользовательском элементе Winforms, например. Пример WPF Control:

<UserControl x:Class="WindowsFormsApplication1.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid> 
     <Rectangle Name="rectangle1" Stroke="White" Fill="Black" RadiusX="10" RadiusY="10" Opacity="0.7" /> 
     <Rectangle Margin="57,101,43,99" Name="dialog" Stroke="Gray" Fill="White" RadiusX="10" RadiusY="10" /> 
    </Grid> 
</UserControl> 

2) Хост пользовательский элемент управления Winforms (содержание) в пределах белого прямоугольника (диалоговом) элемента управления WPF. 3) разрешить контент (пользовательский контроль Winforms) вызывать код родительского элемента WPF-Control.

Первых вещей первый ...

  • Является ли это разумно, что нужно сделать, или я ложное дерево?
  • Можно ли это сделать проще?
  • Может ли кто-нибудь помочь мне здесь? (Образец кода будет с благодарностью получен!)
  • Наконец ... есть ли какие-либо онлайн-ресурсы, которые могут помочь мне а) изучить WPF и b) стать более самодостаточными?
+1

@TK: Прозрачность визуализации, смешанная с WPF и Winforms, является проблемой, и я не знаю, разрешима ли она. WPF и WinForms принципиально отличаются друг от друга, и я помню, где-то читал, что, хотя они могут размещать друг друга, наложенные компоненты не будут отображаться правильно, период. Им нужны разные регионы. Кажется, я читал это в книге Адама Натана, но у меня нет здесь ссылки, поэтому я мог вспомнить неправильно. –

+0

@Greg D: Я считаю, что вы абсолютно правы. Проблема в том, что каждый элемент управления (будь то WPF или Winforms) требует своего собственного воздушного пространства. Это означает, что в любой момент времени пиксель на экране представляет собой пиксель WPF или пиксель Winform и не может быть гибридом двух.Я решил эту проблему, получив компоненты Winforms, чтобы отобразить себя как файл BMP, а затем отобразить файл bmp в качестве фона другого элемента управления. Беспокойно ... да, но кажется, что он работает достаточно хорошо. –

+0

Умный подход. Можете ли вы опубликовать, как вы получили элементы управления winforms для рендеринга в качестве растрового изображения для эффектов смешивания в ответе на ваш вопрос? :) Захватываете ли вы изменения в элементах winforms и соответствующим образом обновляете растровые изображения, или они являются элементами управления winforms, статичными во время эффектов прозрачности? –

ответ

1

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

public class OverlayingControl : UserControl 
{ 
    /// <summary> 
    /// Overrides the c# standard Paint Background to allow the custom background to be drawn 
    /// within the OnPaint function 
    /// </summary> 
    /// 
    /// <param name="e">Arguements used within this function</param> 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     //Do Nothing 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     // Render the Parents image to a Bitmap. NB: bitmap dimensions and Parent Bounds can be changed to achieve the desitred effect 
     Bitmap background = new Bitmap(Width, Height, PixelFormat.Format64bppArgb); 
     Parent.DrawToBitmap(background, Parent.Bounds); 

     // Paint background image    
     g.DrawImage(background, 0, 0, new RectangleF(Location, Size), GraphicsUnit.Pixel); 

     // Perform any alpha-blending here by drawing any desired overlay e.g. 
     // g.FillRectangle(new SolidBrush(semiTransparentColor), Bounds); 
    } 

} 

Это осуществляется исключительно в пределах домена WinForms, однако я считаю, что это может быть возможным, чтобы передать этот Bitmap изображение к элементу управления WPF для визуализации в соответствии с требованиями. В настоящее время нет никаких условий для обновления Bitmap при изменении родителя. Однако для создания настраиваемого метода, который очищает битмап и повторно рисует элемент управления Overlayng, должно быть тривиально. Не изящное решение, которое я понимаю ... но, похоже, он работает достаточно хорошо.

4

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

Я сам не пробовал, but according to this article on CodeProject, это должно быть довольно просто. Вы должны использовать ElementHost control для размещения вашего содержимого WPF.

Хостинг WPF в элементе управления WinForms - поддерживаемый сценарий, встроенный в инфраструктуру. Поэтому не должно быть никаких проблем при этом. Существует также компонент WPF для перехода по другому пути, в котором размещены WinForms в приложении WPF.

+0

Спасибо за ссылку ... ее действительно помогли! Единственная проблема теперь в том, чтобы WPF продемонстрировать свою прозрачность, чтобы показать элементы управления Winforms внизу! На данный момент он полностью непрозрачен в данный момент –