【问题标题】:How to draw on screen for Windows Metro Style Apps in C#?如何在 C# 中为 Windows Metro 风格应用程序在屏幕上绘图?
【发布时间】:2011-11-11 20:20:33
【问题描述】:

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

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

我发现了这个有用的教程:
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.IO; 使用 System.Linq; 使用 System.Threading.Tasks; 使用多媒体.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; 布尔 isTracing = false;

【问题讨论】:

  • 我也找到了这个教程,但仍然没有帮助。 windowsphonegeek.com/tips/…
  • 您已有的代码有什么问题?
  • 我没有在屏幕上绘制任何东西。我不知道用什么来做到这一点。 (顺便说一句,感谢您的评论!)

标签: c# windows coding-style draw microsoft-metro


【解决方案1】:

短格式:

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

Metro/XAML 中无法覆盖OnRender() 方法等。您的选择是将现有的图形元素(例如来自Shapes namespace)添加到画布或其他面板,或者直接操作位图中的像素并将该位图推送到图像元素中。

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

myCanvas.DrawLine( fromPoint, toPoint );

这可以在 JavaScript/HTML 项目中使用 HTML5's Canvas object 完成。可悲的是,这就是我倾向于这样一个项目的方式。不幸的是,微软没有为 XAML 项目提供即时模式元素,但事实就是如此。 C++/DirectX 也是进行自定义绘图的一种选择,但需要对您在应用程序中所做的所有其他事情进行大量修改。

【讨论】:

    【解决方案2】:

    这里有一个很棒的代码示例,介绍了如何使用 XAML 形状来做到这一点。

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        您的代码中的主要问题是您没有附加任何 XAML 元素的行,我建议您对 Canvas 元素执行此操作,而不是像这样:

        newCanvas.Children.Add(line);
        

        另一种方法是使用Modern Components Drawing Library,它适用于 WinRT,使用 .NET Graphics 类调用并直接在 XAML 画布上绘制,请注意,如果要将图像保存为位图,可能需要使用还有WritableBitmapEx,因为 XAML 画布无法呈现为位图。

        【讨论】:

          【解决方案5】:

          此示例项目包含用于在 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> 
          

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多