如何在C#中使用Windows Metro Style应用程序的屏幕?

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

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

我发现这个有用的教程:
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的,所以它有点不同。= \ Help,please?=)

而这就是我迄今为止所拥有的。

绘图部分:

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.IO;
    使用System.Linq;
    使用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 isTracing = false;

简写:

  • LineRectangle添加到面板
  • 直接操作位图
  • 在JavaScript / HTML项目中使用HTML5 Canvas元素
  • 用C ++ / DirectX编写整个事情

Metro / XAML无法重写OnRender()方法等。 您的选择是将现有的图形元素(例如从Shapes命名空间 )添加到Canvas或其他面板,或者直接操作位图中的像素并将该位图推送到Image元素中。

Metro / C#只有保留模式的图形绘制,这意味着它唯一会呈现的是已添加到视图层次结构中的对象。 你正在寻找的是一种即时模式的图形绘制,例如

 myCanvas.DrawLine( fromPoint, toPoint ); 

这可以在使用HTML5的Canvas对象的JavaScript / HTML项目中完成。 不幸的是,我正在为这样一个项目倾斜。 不幸的是,微软并没有为XAML项目提供即时模式元素,但事实就是这样。 C ++ / DirectX也是进行自定义绘制的选项,但是需要对应用中正在做的其他事情进行大量的修改。

下面是一个很好的代码示例,介绍如何使用XAML形状来完成此操作。

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

您应该将该行添加到UI元素(如“画布”)。

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

 newCanvas.Children.Add(line); 

另一种方法是使用现代组件绘图库 ,它在WinRT上工作,使用.NET Graphics类如调用并直接在XAML画布上绘制,注意,如果要将图像保存为位图,则可能还需要使用WritableBitmapEx ,因为XAML Canvas不能渲染到位图。

此示例项目的代码可以在C#/ XAML中的Win 8 Store应用程序的屏幕上绘制:

http://code.msdn.microsoft.com/windowsapps/Drawing-on-a-Canvas-with-33510ae6

这里是相关的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) { } } 

}

和xaml文件:

 <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> 

在目前的状态下,它只处理笔或鼠标的输入 – 但我也只是稍作修改而已。