Avatar billede onkel_satan Nybegynder
10. oktober 2007 - 01:57 Der er 9 kommentarer og
1 løsning

OnRender i WPF

Så er man kommet dertil hvor man lige skal se hvad det presentation foundation er for noget og er derfor igang med at skrive et 'gammlet' program om i WPF. Men jeg er stød ind i et lille problem som måske en af jer kan hjælpe mig. I første omgang skal jeg bare have tegnet en rektangel på en canvas, men der er det lille twist at jeg gerne vil bruge OnRender eventen til at tegne min rektangel. Spørgsmålet er hvordan jeg for den til at 'male' på canvas'en. Her er den kode jer er nået frem til so far.
class Drawingboard : Window
    {
        private Canvas board;
        private Square square1;     

        public Drawingboard() {
            Title = "Drawing board";
            board = new Canvas();
            board.Height = board.Width = Width = Height = 400;
            board.Background = Brushes.Blue;
            Content = board;
        }

        protected override void OnRender(System.Windows.Media.DrawingContext dc) {
            base.OnRender(dc);
            dc.DrawRectangle(Brushes.Green, null, new Rect(10, 10, 10, 10));
           
        }
       
        [STAThread]
        public static void Main() {
            Application app = new Application();
            app.Run(new Drawingboard());
        }
    }

På forhånd tak.
Avatar billede nielle Nybegynder
10. oktober 2007 - 08:37 #1
I modsætning til en "gammeldags" Forms applikation bliver OnRender i WPF ikke kaldt særlig tit. Faktisk (vist) kun når formen vises første gang, og så når du selv kalder:

InvalidateVisual()

Resten af tiden bruges der en cachet version. Dette har noget at gøre med den måde grafik accelereringen virker i WPF.
Avatar billede nielle Nybegynder
16. oktober 2007 - 09:21 #2
Hvad med lidt respons?
Avatar billede onkel_satan Nybegynder
16. oktober 2007 - 15:03 #3
Hej, sorry jeg ikke lige fulgte op på mit spørgsmål, men en anden opgave overtog lidt mit focus på WPF. Men kan du sige noget om hvor ofte OnRender bliver kaldt eller hvad kan evt. ellers skulle bruge istedet for ?
Avatar billede nielle Nybegynder
16. oktober 2007 - 16:24 #4
Jeg har vist allerede fortalt hvornår OnRender kaldes. :^)

Den rigtige metode er at bruge OnRender, så du er ikke på vej galt i byen med din kode. Du skal blot være klar over at du selv skal kalde InvalidateVisual()
når du vil have opdateret med nyt indhold.
Avatar billede onkel_satan Nybegynder
16. oktober 2007 - 16:43 #5
Ok, så OnRender bliver altså kun kaldt ved invalidateVisual.
Derfor prøvede jeg at kalde invalidateVisual() som det sidste i constructer'en men der kommer stadig ingen firkant. Det jeg grubler lidt over er at OnRender kommer fra Window classen, det vil vel sige at den skriver på Drawingboard (hvilket den jo saa alligevel ikke gør) og ikke på canvas'en som jeg gerne vil have den til. Canvas'en har jo også sit eget DrawingContext (hvis jeg husker rigtigt) så det hele er pt. lidt forvirrende. Hvis du kunne/har tid til at illustrere hvordan mit eksemple udføres korrekt ville det være super :D
Hvis ikke saa skal jeg nok vende tilbage når jeg har fået det til at virke saa andre måske kan få gavn af det. Er jo ikke meget man ser til WPF (endnu ?).
Har faktisk lige købt en bog (MS application: code+markup. A guide to WPF), så håber den kan kaste lidt lys på hvordan hele drawing systemet er skruget sammen.
Avatar billede nielle Nybegynder
17. oktober 2007 - 19:27 #6
Efter at have tygget lidt på det du skrev, kom jeg frem til denne her. Den viser firkanten :^)

Opret en klasse som arver fra Canvas:

    class MyCanvas : Canvas
    {
        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            drawingContext.DrawRectangle(Brushes.Green, null, new Rect(10, 10, 10, 10));
        }
    }

OnRender metoden flyttes til den.

Når du opretter dit Drawingboard, er det den du indsætter som Canvas:

    class Drawingboard : Window
    {
        private Canvas board;
        // private Square square1;

        public Drawingboard()
        {
            Title = "Drawing board";
            board = new MyCanvas();
            board.Height = board.Width = Width = Height = 400;
            board.Background = Brushes.Blue;
            Content = board;
        }

        //protected override void OnRender(System.Windows.Media.DrawingContext dc)
        //{
        //    base.OnRender(dc);
        //    dc.DrawRectangle(Brushes.Green, null, new Rect(10, 10, 10, 10));
        //}

        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new Drawingboard());
        }
    }
Avatar billede onkel_satan Nybegynder
18. oktober 2007 - 11:55 #7
Super, det ser jo fint ud. Det ligner også lidt det der står i min bog. Er pt ved at se hvordan jeg gruppere grafiske objekter. I det 'gamle' c# benyttede jeg mig af composite pattern til at holde styr på min grafiske objekter, men WPF har noget content holder som muligvis gør det samme. Anyways saa smid et svar så du kan få lidt point. Vil stadig vende tilbage med min version naar jeg kommer dertil :D
Avatar billede nielle Nybegynder
18. oktober 2007 - 12:14 #8
Mon ikke de havde tænkt sig at man skulle gøre det med XAML i WPF?

... og et svar :^)
Avatar billede onkel_satan Nybegynder
18. oktober 2007 - 13:33 #9
Ja det er jo saa den anden del af WPF. Men til at begynde med syntes jeg altid det er best med at skrive koden selv, giver også en bedre forståelse.
Avatar billede onkel_satan Nybegynder
23. oktober 2007 - 18:28 #10
Saa fandt jeg ud af hvordan jeg ville sætte det op.

class MyWin : Window
{
    private MyCanvas board;
    public MyWin(){
        Title = "Drawing board";
        board = new MyCanvas();
        board.Height = board.Width = Width = Height = 400;
        board.Background = Brushes.White;
        Content = board;
    }
   
    [STAThread]
    public static void Main(){
        Application app = new Application();
        app.Run(new UMLApp());
    }
}
   
class MyCanvas : Canvas
    {
        private MySquare square1;

        public MyCanvas()
        {
            square1 = new MySquare();
        }

        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);
            square1.draw(dc);
        }
    }

class MySquare
{
    public void draw(DrawingContext dc){
        dc.DrawRectangle(Brushes.Blue, null , new Rect(10, 10, 10, 10)));
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester