如何在c#中为Windows Metro风格的应用程序绘制屏幕

本文关键字:风格 应用程序 绘制 屏幕 Metro Windows 中为 | 更新日期: 2023-09-27 18:14:08

我只是希望用户能够用某种指针在屏幕上绘图。

我已经有了捕获指针位置的代码,但我不知道如何将像素或形状或任何东西放在屏幕上。

我发现了这个有用的教程:
http://www.dotnetspeaks.com/DisplayArticle.aspx?ID=137

我一直在看这里的文档:
http://msdn.microsoft.com/en-us/library/windows/apps/hh465055 (v = VS.85) . aspx

到目前为止还没有运气。这个教程是针对Windows Phone 7的,所以有点不同。请帮忙?=)

这是我目前得到的。

绘图部分:

    private void Image_PointerPressed(object sender, PointerEventArgs e)
    {
        Debug.WriteLine("Image_PointerPressed");
        isTracing = true;
    }
    private void Image_PointerReleased(object sender, PointerEventArgs e)
    {
        Debug.WriteLine("Image_PointerReleased");
        isTracing = false;
    }
    private void Image_PointerMoved(object sender, PointerEventArgs e)
    {
        Debug.WriteLine("Image_PointerMoved");
        Debug.WriteLine(e.GetCurrentPoint(this).Position);
        if (isTracing)
        {
            Debug.WriteLine("isTracing");
            Point pos = e.GetCurrentPoint(this).Position;
            Color color = Colors.Green;
            Line line = new Line() { X1 = pos.X, X2 = pos.X + 1, Y1 = pos.Y, Y2 = pos.Y + 1 };
            line.Stroke = new SolidColorBrush(color);
            line.StrokeThickness = 15;
            //// So how do I draw this line onto the screen?? ////
        }
    }

作为参考,代码中其他地方的东西:

<>之前使用系统;使用System.Collections.Generic;使用System.Diagnostics;使用先;使用来;使用System.Threading.Tasks;使用Multimedia.FFmpeg;使用Windows.Foundation;使用Windows.Storage;使用Windows.Storage.Pickers;使用Windows.Storage.Streams;使用Windows.UI.Xaml;使用Windows.UI.Xaml.Controls;使用Windows.UI.Xaml.Shapes;使用Windows.UI.Xaml.Media;使用Windows.UI.Xaml.Input;使用Windows.UI.Input;bool istring = false;

如何在c#中为Windows Metro风格的应用程序绘制屏幕

简写:

  • 添加Line s和Rectangle s到面板
  • 直接操作位图
  • 在JavaScript/HTML项目中使用HTML5 Canvas元素
  • 用c++/DirectX编写整个程序
在Metro/XAML中没有办法覆盖OnRender()方法或类似的方法。你的选择是将现有的图形元素(例如从形状命名空间)添加到画布或其他面板,或者直接操作位图中的像素并将该位图推入图像元素。

Metro/c#只有保留模式的图形绘制,这意味着它只会渲染已经添加到视图层次结构中的对象。你要找的是某种即时模式的图形绘制,例如

myCanvas.DrawLine( fromPoint, toPoint );

这可以在JavaScript/HTML项目中使用HTML5的Canvas对象完成。可悲的是,这就是我对这样一个项目的学习方式。不幸的是,微软没有为XAML项目提供即时模式元素,但这就是它的方式。c++/DirectX也是一个自定义绘图的选项,但需要大量的重做你在应用程序中所做的一切。

这里有一个很好的代码示例,说明如何使用XAML形状来做到这一点。

http://www.codeproject.com/Articles/416878/Metro-Paint

您应该将Line添加到UI元素中,例如Canvas

在你的代码的主要问题是,你没有附加,行到任何XAML元素,我建议你做一个画布元素,更少像这样:

newCanvas.Children.Add(line);

另一种选择是使用Modern Components Drawing Library,它可以在WinRT上工作,使用。net Graphics类(如调用)并直接在XAML Canvas上绘制,注意如果你想将图像保存为位图,你可能还需要使用WritableBitmapEx,因为XAML Canvas不能渲染为位图。

这个示例项目用c#/XAML在屏幕上绘制win8 Store应用程序的代码:

http://code.msdn.microsoft.com/windowsapps/drawing——一个画布上-和- 33510 - ae6

下面是相关的c#文件:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using Windows.Devices.Input; 
using Windows.Foundation; 
using Windows.Foundation.Collections; 
using Windows.UI; 
using Windows.UI.Input; 
using Windows.UI.Input.Inking; //we need to add this name space in order to have many functions  
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Controls.Primitives; 
using Windows.UI.Xaml.Data; 
using Windows.UI.Xaml.Input; 
using Windows.UI.Xaml.Media; 
using Windows.UI.Xaml.Navigation; 
using Windows.UI.Xaml.Shapes; 
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 
namespace DrawingOnCanvasWithInkPen 
{ 
/// <summary> 
/// An empty page that can be used on its own or navigated to within a Frame. 
/// </summary> 
public sealed partial class MainPage : Page 
{ 
    InkManager _inkKhaled = new Windows.UI.Input.Inking.InkManager(); 
    private uint _penID; 
    private uint _touchID; 
    private Point _previousContactPt; 
    private Point currentContactPt; 
    private double x1; 
    private double y1; 
    private double x2; 
    private double y2; 

    public MainPage() 
    { 
        this.InitializeComponent(); 
        MyCanvas.PointerPressed += new PointerEventHandler(MyCanvas_PointerPressed); 
        MyCanvas.PointerMoved += new PointerEventHandler(MyCanvas_PointerMoved); 
        MyCanvas.PointerReleased += new PointerEventHandler(MyCanvas_PointerReleased); 
        MyCanvas.PointerExited += new PointerEventHandler(MyCanvas_PointerReleased); 
    } 

    #region PointerEvents 
    private void MyCanvas_PointerReleased(object sender, PointerRoutedEventArgs e) 
    { 
        if (e.Pointer.PointerId == _penID) 
        { 
            Windows.UI.Input.PointerPoint pt = e.GetCurrentPoint(MyCanvas); 
            // Pass the pointer information to the InkManager.  
            _inkKhaled.ProcessPointerUp(pt); 
        } 
        else if (e.Pointer.PointerId == _touchID) 
        { 
            // Process touch input 
        } 
        _touchID = 0; 
        _penID = 0; 
        // Call an application-defined function to render the ink strokes. 

        e.Handled = true; 
    } 
    private void MyCanvas_PointerMoved(object sender, PointerRoutedEventArgs e) 
    { 
        if (e.Pointer.PointerId == _penID) 
        { 
            PointerPoint pt = e.GetCurrentPoint(MyCanvas); 
            // Render a red line on the canvas as the pointer moves.  
            // Distance() is an application-defined function that tests 
            // whether the pointer has moved far enough to justify  
            // drawing a new line. 
            currentContactPt = pt.Position; 
            x1 = _previousContactPt.X; 
            y1 = _previousContactPt.Y; 
            x2 = currentContactPt.X; 
            y2 = currentContactPt.Y; 
            if (Distance(x1, y1, x2, y2) > 2.0) // We need to developp this method now  
            { 
                Line line = new Line() 
                { 
                    X1 = x1, 
                    Y1 = y1, 
                    X2 = x2, 
                    Y2 = y2, 
                    StrokeThickness = 4.0, 
                    Stroke = new SolidColorBrush(Colors.Green) 
                }; 
                _previousContactPt = currentContactPt; 
                // Draw the line on the canvas by adding the Line object as 
                // a child of the Canvas object. 
                MyCanvas.Children.Add(line); 
                // Pass the pointer information to the InkManager. 
                _inkKhaled.ProcessPointerUpdate(pt); 
            } 
        } 
        else if (e.Pointer.PointerId == _touchID) 
        { 
            // Process touch input 
        } 
    } 
    private double Distance(double x1, double y1, double x2, double y2) 
    { 
        double d = 0; 
        d = Math.Sqrt(Math.Pow((x2 - x1), 2) + Math.Pow((y2 - y1), 2)); 
        return d; 
    } 
    private void MyCanvas_PointerPressed(object sender, PointerRoutedEventArgs e) 
    { 
        // Get information about the pointer location. 
        PointerPoint pt = e.GetCurrentPoint(MyCanvas); 
        _previousContactPt = pt.Position; 
        // Accept input only from a pen or mouse with the left button pressed.  
        PointerDeviceType pointerDevType = e.Pointer.PointerDeviceType; 
        if (pointerDevType == PointerDeviceType.Pen || 
                pointerDevType == PointerDeviceType.Mouse && 
                pt.Properties.IsLeftButtonPressed) 
        { 
            // Pass the pointer information to the InkManager. 
            _inkKhaled.ProcessPointerDown(pt); 
            _penID = pt.PointerId; 
            e.Handled = true; 
        } 
        else if (pointerDevType == PointerDeviceType.Touch) 
        { 
            // Process touch input 
        } 
    } 
    #endregion 
    /// <summary> 
    /// Invoked when this page is about to be displayed in a Frame. 
    /// </summary> 
    /// <param name="e">Event data that describes how this page was reached.  The Parameter 
    /// property is typically used to configure the page.</param> 
    protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
    } 
} 

}

and

<Page 
x:Class="DrawingOnCanvasWithInkPen.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="using:DrawingOnCanvasWithInkPen" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d"> 
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> 
    <Canvas Name="MyCanvas" Background="White" HorizontalAlignment="Left" Height="513" Margin="83,102,0,0" VerticalAlignment="Top" Width="1056"/> 
</Grid> 

在目前的状态下,它只能处理笔或鼠标输入——但我也让它在触摸时工作,只需要稍微修改一下。