How to draw on a Window in WPF (best practice)?

前端 未结 5 468
无人及你
无人及你 2021-02-01 04:01

I am trying to write a small interactive game-like application, where I need to have a Draw method that\'s gonna draw on screen, but can\'t figure out how to struct

相关标签:
5条回答
  • 2021-02-01 04:17

    Yow should add a Canvas (or change the Grid for a Canvas) and then draw over it. Here is Microsoft tut on drawing over a canvas

    Also, I don't know how related is this other question to yours, but you might want to check it out.

    0 讨论(0)
  • 2021-02-01 04:22

    Typically, you "draw" in WPF in a completely different manner.

    In Windows Forms/GDI, the graphics API is an immediate mode graphics API. Each time the window is refreshed/invalidated, you explicitly draw the contents using Graphics.

    In WPF, however, things work differently. You rarely ever directly draw - instead, it's a retained mode graphics API. You tell WPF where you want the objects, and it takes care of the drawing for you.

    The best way to think of it is, in Windows Forms, you'd say "Draw a line from X1 to Y1. Then draw a line from X2 to Y2. Then ...". And you repeat this every time you need to "redraw" since the screen is invalidated.

    In WPF, instead, you say "I want a line from X1 to Y1. I want a line from X2 to Y2." WPF then decides when and how to draw it for you.

    This is done by placing the shapes on a Canvas, and then letting WPF do all of the hard work.

    0 讨论(0)
  • 2021-02-01 04:22

    To Implement a Draw loop type behavior in WPF you can use the CompositionTarget.Rendering event. This is raised once per frame when the WPF drawing system is painting frames.

    As others have pointed out this is not very WPF friendly but it will work and can be used to get more immediate drawing behavior out of a WPF app.

    In most cases you would use a single root canvas and update say the Canvas position of an element on the CompositionTarget.Rendering event.

    For example to make a ellipse fly all over the screen do this:

    In your XAML (For a Window that is 640 by 480 in size):

    <Canvas x:Name="theCanvas">
        <Ellipse x:Name="theEllipse" Height="10" Width="10" Fill="Black" />     
    </Canvas>
    

    In your Code behind for the Window that the above XAML is in (Make sure to add a reference to System.Windows.Media in order to see the CompsitionTarget object :

        public static Random rand = new Random();
        public View()
        {
            InitializeComponent();
            CompositionTarget.Rendering += CompositionTarget_Rendering;
        }
    
        void CompositionTarget_Rendering(object sender, System.EventArgs e)
        {
            double newLeft = rand.Next(0, 640);
            double newTop = rand.Next(0, 480);
    
            theEllipse.SetValue(Canvas.LeftProperty,newLeft);
            theEllipse.SetValue(Canvas.TopProperty, newTop);
        }
    
    0 讨论(0)
  • 2021-02-01 04:31

    When there are just too many objects to be drawn very quickly (huge Visual Tree) another option would be to use a WriteableBitmap. Just use the Pixels property to set the pixels and/or use the Render method to draw UIElements.

    0 讨论(0)
  • 2021-02-01 04:39

    I preffer to use OnRender method like in this example:

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
         drawingContext.DrawRectangle(null, new Pen(Brushes.Black, 2), new Rect(0, 0, ActualWidth, Height));
    }
    
    0 讨论(0)
提交回复
热议问题