C ++ / cli переопределяет событие OnRender wpf

я пытаюсь принести wpf «огонь» (http://www.smartypantscoding.com/content/old-school-fire-algorithm-modern-day-wpf) Пример для c ++ / cli. Я перевел его с помощью инструмента на c ++ / cli, но переопределенное событие OnRender никогда не запускалось. Так что я вижу окно, как в проекте C #, но без огня.

CompositionTarget_Rendering вызывается, и поэтому обычно InvalidateVisual () должен запускать OnRender, но это не так. Я надеюсь ты сможешь мне помочь =)

//the .h
#pragma once
using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::Globalization;
using namespace System::Xml::Linq;
using namespace System::Text;
using namespace System::Windows::Documents;
using namespace System::Windows;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Threading;
#include "FireGenerator.h"

/// <summary>
/// Adorner that disables all controls that fall under it
/// </summary>
public ref class FireAdorner : Adorner
{
private:
BitmapPalette ^_pallette;
literal int DPI = 96;
FireGenerator ^_fireGenerator;

/// <summary>
/// Constructor for the adorner
/// </summary>
/// <param name="adornerElement">The element to be adorned</param>
public:
FireAdorner(UIElement^ adornerElement);private:
void CompositionTarget_Rendering(Object ^sender, EventArgs ^e);

/// <summary>
/// Called to draw on screen
/// </summary>
/// <param name="drawingContext">The drawind context in which we can draw</param>
protected:

virtual void OnRender(System::Windows::Media::DrawingContext ^drawingContext) override;private:
BitmapPalette ^SetupFirePalette();

private:
void InitializeInstanceFields();
};

и .cpp

#include "StdAfx.h"#include "FireAdorner.h"

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;
using namespace System::Globalization;
using namespace System::Xml::Linq;
using namespace System::Text;
using namespace System::Windows::Documents;
using namespace System::Windows;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Threading;FireAdorner::FireAdorner(UIElement ^adornerElement) : Adorner(adornerElement)
{
InitializeInstanceFields();
CompositionTarget::Rendering += gcnew EventHandler(this, &FireAdorner::CompositionTarget_Rendering);

}

void FireAdorner::CompositionTarget_Rendering(Object ^sender, EventArgs ^e)
{
InvalidateVisual();

}void FireAdorner::OnRender(System::Windows::Media::DrawingContext ^drawingContext)
{
System::Windows::MessageBox::Show("render");
// only set the pallette once (dont do in constructor as causes odd errors if exception occurs)
if (_pallette == nullptr)
{
_pallette = SetupFirePalette();
}

_fireGenerator->UpdateFire();

BitmapSource ^bs = BitmapSource::Create(_fireGenerator->Width, _fireGenerator->Height, DPI, DPI, PixelFormats::Indexed8, _pallette, _fireGenerator->FireData, _fireGenerator->Width);
drawingContext->DrawImage(bs, Rect(0, 0, this->DesiredSize.Width, this->DesiredSize.Height));}

BitmapPalette ^FireAdorner::SetupFirePalette()
{
System::Collections::Generic::List<Color> ^myList = gcnew System::Collections::Generic::List<Color>();

// seutp the basic array we will modify
for (int i = 0; i <= 255; i++)
{
myList->Add(Color());
}

for (int i = 0; i < 64; i++)
{
Color c1 = Color();
c1.R = safe_cast<Byte>(i * 4);
c1.G = safe_cast<Byte>(0);
c1.B = safe_cast<Byte>(0);
c1.A = 255;
myList[i] = c1;

Color c2 = Color();
c2.R = safe_cast<Byte>(255);
c2.G = safe_cast<Byte>(i * 4);
c2.B = safe_cast<Byte>(0);
c2.A = 255;
myList[i + 64] = c2;

Color c3 = Color();
c3.R = safe_cast<Byte>(255);
c3.G = safe_cast<Byte>(255);
c3.B = safe_cast<Byte>(i * 4);
c3.A = 255;
myList[i + 128] = c3;

Color c4 = Color();
c4.R = safe_cast<Byte>(255);
c4.G = safe_cast<Byte>(255);
c4.B = safe_cast<Byte>(255);
c4.A = 255;
myList[i + 192] = c4;
}

BitmapPalette ^bp = gcnew BitmapPalette(myList);
return bp;
}

void FireAdorner::InitializeInstanceFields()
{
_fireGenerator = gcnew FireGenerator(600, 50);
}

Initcode:

FireAdorner^ myfire = gcnew FireAdorner(MyWindow);
MyWindow->ShowDialog();

// MyWindow — это окно ^, созданное из этого кода:

<Window     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="WPF Fire" Width="800" Height="200" Closing="Window_Closing">
<Grid>
<AdornerDecorator>
<DockPanel Name="dockPanel1"/>
</AdornerDecorator>

<!-- This rectangle is a hack to hide the bottom rows of the fire which look blocky
the proper solution would be to fix the rendering to leave off the bottom XX lines -->
<Rectangle Fill="Black" VerticalAlignment="Bottom"Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=ActualWidth}"Height="8" />
</Grid>
</Window>

0

Решение

Это решило проблему:

старый не работает Initcode:

FireAdorner^ myfire = gcnew FireAdorner(MyWindow);
MyWindow->ShowDialog();

новый Initcode:

DockPanel^ firebox = (DockPanel^)MyWindow->FindName("dockPanel1");
AdornerLayer^ adornerLayer = AdornerLayer::GetAdornerLayer(firebox);
adornerLayer->Add(gcnew FireAdorner(firebox));
MyWindow->ShowDialog();
0

Другие решения


По вопросам рекламы [email protected]