#c# #windows #coding-style #draw #microsoft-metro
#c# #Windows #стиль кодирования #рисовать #microsoft-metro
Вопрос:
Я просто хочу, чтобы пользователь мог рисовать на экране с помощью какого-либо указателя.
У меня уже есть работающий код, который фиксирует положение указателя, но я не могу понять, как разместить пиксели, фигуры или что-то еще на экране.
Я нашел это полезное руководство:
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.Коллекции.Общий; использование System.Диагностика; использование System.Ввод-вывод; используя System.Linq; использование System.Многопоточность.Задачи; использование мультимедиа.FFmpeg; использование Windows.Основа; использование Windows.Хранение; использование Windows.Хранение.Средства выбора; использование Windows.Хранение.Стримы; использование Windows.UI.Xaml; использование Windows.UI.Xaml.Controls; использование Windows.UI.Xaml.Shapes; использование Windows.UI.Xaml.Media; используя Windows.UI.Xaml.Ввод; использование Windows.UI.Input; bool isstracing = false;
Комментарии:
1. Я также нашел это руководство, но оно все равно не помогло. windowsphonegeek.com/tips /…
2. Что не работает правильно в коде, который у вас уже есть?
3. Я ничего не рисую на экране. Я не знаю, что использовать для этого. (Кстати, спасибо за комментарий!)
Ответ №1:
Краткая форма:
- Добавьте
Line
s иRectangle
s на панель - Напрямую манипулировать растровым изображением
- Используйте элемент Canvas HTML5 в проекте JavaScript / HTML
- Напишите все это на C / DirectX
В Metro / XAML нет способа переопределить OnRender()
метод или подобное. Вы можете добавлять существующие графические элементы (например, из пространства имен Shapes) на холст или другую панель или напрямую манипулировать пикселями в растровом изображении и помещать это растровое изображение в элемент изображения.
В Metro / C # сохранен только графический режим рисования, что означает, что единственное, что он будет отображать, — это объекты, которые были добавлены в иерархию представлений. То, что вы ищете, это какой-то графический рисунок в немедленном режиме, например
myCanvas.DrawLine( fromPoint, toPoint );
Это можно сделать в проекте JavaScript / HTML, используя объект Canvas в HTML5. К сожалению, я склоняюсь к такому проекту. К сожалению, Microsoft не предоставляет элемент немедленного режима для проектов XAML, но так оно и есть. C / DirectX также является опцией для выполнения пользовательского рисования, но требует существенной переработки всего остального, что вы делаете в приложении.
Ответ №2:
Вот отличный пример кода о том, как это сделать, используя формы XAML.
Ответ №3:
Вы должны добавить строку к элементу пользовательского интерфейса, такому как холст.
Ответ №4:
Основная проблема в вашем коде заключается в том, что вы не прикрепляете строку к какому-либо элементу XAML, я предлагаю вам сделать это к элементу Canvas, примерно так:
newCanvas.Children.Add(line);
Альтернативой является использование библиотеки рисования современных компонентов, она работает на WinRT, использует вызовы класса .NET Graphics like и рисует непосредственно на XAML Canvas, обратите внимание, что если вы хотите сохранить изображение в виде растрового изображения, вам может потребоваться также использовать WritableBitmapEx, поскольку XAML Canvas нельзя отобразить в виде растровых изображений.
Ответ №5:
В этом примере проекта есть код для рисования на экране для приложений магазина Win 8 на C # / XAML:
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 amp;amp;
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>
В своем текущем состоянии он обрабатывает только ввод с помощью пера или мыши — но я также заставил его работать для touch с небольшими изменениями.