PDA

View Full Version : گرافیک C#



mohsen_csharp
چهارشنبه 10 بهمن 1386, 11:57 صبح
فرض کنید از یک پنل به عنوان محیط گرافیکی استفاده می کنم و اشکالی را روی آن می کشم.
گاهی اوقات شکلی روی شکل دیگری کشیده می شود.
می خواهم برنامه قابلیت ctrl+z را داشته باشد و این شکل آخری را پاک کند ولی نمی دانم قبلا زیر آن چه شکلی بوده که مجدداً آن را ترسیم نمایم!
آیا مکانیزمی وجود دارد که شکل های کشیده شده روی پنل را به عنوان یک شکل گرافیکی ذخیره و بازیابی کرد؟
در ضمن از عکس نمی خواهم استفاده کنم چون پردازش برنامه من زیاد است!

رها
چهارشنبه 10 بهمن 1386, 12:22 عصر
بهتره روند عملیات طی شده رو در یک جایی نگه داری
مسلماً نقاشی کشیدن در رویدادهای خاصی اجرا می شه پس بهتره بعد از رسم، کاری رو که انجام دادی در یک ساختاری مثل لیست ذخیره کنی اونوقت می تونی عمل Undo رو به صورت اجرا از ابتدا تا نقطه ای که مایلی، انجام بدی

Masoud_TB
چهارشنبه 10 بهمن 1386, 14:14 عصر
سلام.
بهترین راه حل برای پیاده سازی Undo استفاده و پیاده سازی یکی از Design Pattern iها به نام Decorator که نه همان Command می باشد.
نمی دونم چرا قبلا Decorator‌توی ذهنم اومد ولی درستش همون Command‌است :لبخندساده:

sinpin
چهارشنبه 10 بهمن 1386, 15:24 عصر
سلام.
بهترین راه حل برای پیاده سازی Undo استفاده و پیاده سازی یکی از Design Pattern iها به نام Decorator می باشد.
مسعود جان فکر میکنم منظورتون الگوی Command بوده.

http://www.dofactory.com/Patterns/PatternCommand.aspx

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

mohsen_csharp
چهارشنبه 10 بهمن 1386, 23:46 عصر
با تشکر از دوستان
همان طور که عرض کردم پردازش برنامه من زیاد است.
به عنوان مثال با موس می توان این شکل های گرافیکی را روی یکدیگر حرکت داد و باید دستورات لازم در رویداد mouse move نوشته شود که تکرار این رویداد بسیار سریع است و نمی توان در هر بار اجرای رویداد ، شکل های قبلی را دوباره رسم کرد.
ممکن است در مورد pattern command کمی توضیح دهید و از آن در برنامه خود چگونه استفاده کنم.

sinpin
پنج شنبه 11 بهمن 1386, 10:16 صبح
ممکن است در مورد pattern command کمی توضیح دهید و از آن در برنامه خود چگونه استفاده کنم.
با استفاده از این الگو میتوان درخواستها و تراکنش ها رو در قالب یک آبجکت Encapsulate کرد.


// Command pattern -- Real World example

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Command.RealWorld
{

// MainApp test application

class MainApp
{
static void Main()
{
// Create user and let her compute
User user = new User();

user.Compute('+', 100);
user.Compute('-', 50);
user.Compute('*', 10);
user.Compute('/', 2);

// Undo 4 commands
user.Undo(4);

// Redo 3 commands
user.Redo(3);

// Wait for user
Console.Read();
}
}

// "Command"

abstract class Command
{
public abstract void Execute();
public abstract void UnExecute();
}

// "ConcreteCommand"

class CalculatorCommand : Command
{
char @operator;
int operand;
Calculator calculator;

// Constructor
public CalculatorCommand(Calculator calculator,
char @operator, int operand)
{
this.calculator = calculator;
this.@operator = @operator;
this.operand = operand;
}

public char Operator
{
set{ @operator = value; }
}

public int Operand
{
set{ operand = value; }
}

public override void Execute()
{
calculator.Operation(@operator, operand);
}

public override void UnExecute()
{
calculator.Operation(Undo(@operator), operand);
}

// Private helper function
private char Undo(char @operator)
{
char undo;
switch(@operator)
{
case '+': undo = '-'; break;
case '-': undo = '+'; break;
case '*': undo = '/'; break;
case '/': undo = '*'; break;
default : undo = ' '; break;
}
return undo;
}
}

// "Receiver"

class Calculator
{
private int curr = 0;

public void Operation(char @operator, int operand)
{
switch(@operator)
{
case '+': curr += operand; break;
case '-': curr -= operand; break;
case '*': curr *= operand; break;
case '/': curr /= operand; break;
}
Console.WriteLine(
"Current value = {0,3} (following {1} {2})",
curr, @operator, operand);
}
}

// "Invoker"

class User
{
// Initializers
private Calculator calculator = new Calculator();
private ArrayList commands = new ArrayList();

private int current = 0;

public void Redo(int levels)
{
Console.WriteLine("\n---- Redo {0} levels ", levels);
// Perform redo operations
for (int i = 0; i < levels; i++)
{
if (current < commands.Count - 1)
{
Command command = commands[current++] as Command;
command.Execute();
}
}
}

public void Undo(int levels)
{
Console.WriteLine("\n---- Undo {0} levels ", levels);
// Perform undo operations
for (int i = 0; i < levels; i++)
{
if (current > 0)
{
Command command = commands[--current] as Command;
command.UnExecute();
}
}
}

public void Compute(char @operator, int operand)
{
// Create command operation and execute it
Command command = new CalculatorCommand(
calculator, @operator, operand);
command.Execute();

// Add command to undo list
commands.Add(command);
current++;
}
}
}

sinpin
پنج شنبه 11 بهمن 1386, 14:56 عصر
این لینک رو ببینید. یک برنامه ترسیم است (شاید مشابه برنامه شما) با قابلیت Undo/Redo که با استفاده از Command Pattern پیاده سازی شده :
http://www.codeproject.com/KB/graphics/drawtools.aspx
http://www.codeproject.com/KB/graphics/drawtools/DrawTools.jpg (http://www.codeproject.com/KB/graphics/drawtools.aspx)

Undo-Redo functionality is added to the program using the article The Command Pattern and MVC Architectures (http://www.codeproject.com/cs/design/commandpatterndemo.asp) by David Veeneman. Class Command is abstract base class for all commands representing user activity: CommandAdd, CommandChangeState, CommandDelete, CommandDeleteAll. Every Command-derived class can make two basic operations: Undo which returns draw area to the state before executing this command, and Redo which executes this command again. CommandChangeState is used for resizing, moving of objects and changing objects properties. Class UndoManager keeps list of executed commands (history) and makes operations Undo, Redo and Add command to History. Undo-Redo functionality is implemented only in 2005 version of DrawTools project.


http://www.codeproject.com/KB/WPF/WPF_DrawTools.aspx
http://www.codeproject.com/KB/WPF/WPF_DrawTools/DT_Default.jpg (http://www.codeproject.com/KB/WPF/WPF_DrawTools.aspx)

The UndoManager class manages Undo-Redo operations. It contains the command history, a list of CommandBase-derived classes. Every command class keeps enough information to allow it to undo or redo the command. CommandChangeState is used for every change to existing objects: Move, Resize, Set Properties. An instance of this class is added to the History when one of these actions is executed. CommandAdd is used when a new object is added to the canvas. CommandDelete and CommandDeleteAll are used for deleting.


اینم چند لینک مرتبط:
http://www.codeproject.com/KB/architecture/sharped.aspx
http://www.codeproject.com/KB/cs/AutomatingUndoRedo.aspx
http://www.codeproject.com/KB/cs/reversibleundoredo.aspx

mohsen_csharp
شنبه 13 بهمن 1386, 14:28 عصر
با تشکر از آقا سینا و آقا مسعود ،
ببینید دوستان من یک محیط گرافیکی دارم که شکل هایی را روی آن رسم کرده ام.
فرض کنید که یک مربع توپر رسم کرده ام.سپس دو خط به صورت ضربدری که قطر های مربع را تشکیل می دهند را رسم کرده ام.حالا درون مربع یک دایره توپر رسم می کنم.

حالا فرض کنید می خواهم دایره را پاک کنم که همان undo می باشد.
در مثال هایی که من بررسی کردم عملیات undo برای عملگر ضرب، عملگر تقسیم می باشد.
و عملیات undo برای عملگر تفریق ، عملگر جمع می باشد والی آخر.

حالا برای پاک کردن دایره ای که کشیده ام، عملیات undo چگونه تعریف می کردد؟
اگر دایره ای سفید رنگ روی آن رسم کنم تا آن را پاک کرده باشم، شکل به مربعی که از درون آن دایره ای برداشته اند تبدیل می شود و قطر ها ی مربع نیز که قبلا کشیده بودم ، ناقص می شود.
پس مجبورم همه شکل ها را به ترتیب از اول رسم کنم.

حالا فرض کنید که من هزار تا شکل مختلف روی هم رسم کرده باشم و بخواهم توسط رویداد mouse move ، یک دایره را روی این شکل ها حرکت دهم و به به ازای هر بار اجرا شدن این رویداد همه شکل ها را دوباره رسم کنم. پردازش برنامه بسیار زیاد می شود و این روش هم عملی نیست.

بهترین راه حلی که به ذهن من رسیده آن است که با محاسبات ریاضی بررسی کنم که آن شکلی که روی شکل های دیگر در حال حرکت است ، از روی کدام شکل ها عبور می کند آن شکل ها را به ترتیب رسم می کنم با این کار پردازش برنامه کمتر می شود.

حالا اگر دوستان راه حل بهتری دارند لطفا نظرشان را اعلام کنند.ممنون.

sinpin
شنبه 13 بهمن 1386, 14:52 عصر
با تشکر از آقا سینا و آقا مسعود ،
ببینید دوستان من یک محیط گرافیکی دارم که شکل هایی را روی آن رسم کرده ام.
فرض کنید که یک مربع توپر رسم کرده ام.سپس دو خط به صورت ضربدری که قطر های مربع را تشکیل می دهند را رسم کرده ام.حالا درون مربع یک دایره توپر رسم می کنم.

حالا فرض کنید می خواهم دایره را پاک کنم که همان undo می باشد.
در مثال هایی که من بررسی کردم عملیات undo برای عملگر ضرب، عملگر تقسیم می باشد.
و عملیات undo برای عملگر تفریق ، عملگر جمع می باشد والی آخر.

حالا برای پاک کردن دایره ای که کشیده ام، عملیات undo چگونه تعریف می کردد؟
اگر دایره ای سفید رنگ روی آن رسم کنم تا آن را پاک کرده باشم، شکل به مربعی که از درون آن دایره ای برداشته اند تبدیل می شود و قطر ها ی مربع نیز که قبلا کشیده بودم ، ناقص می شود.
پس مجبورم همه شکل ها را به ترتیب از اول رسم کنم.

حالا فرض کنید که من هزار تا شکل مختلف روی هم رسم کرده باشم و بخواهم توسط رویداد mouse move ، یک دایره را روی این شکل ها حرکت دهم و به به ازای هر بار اجرا شدن این رویداد همه شکل ها را دوباره رسم کنم. پردازش برنامه بسیار زیاد می شود و این روش هم عملی نیست.

بهترین راه حلی که به ذهن من رسیده آن است که با محاسبات ریاضی بررسی کنم که آن شکلی که روی شکل های دیگر در حال حرکت است ، از روی کدام شکل ها عبور می کند آن شکل ها را به ترتیب رسم می کنم با این کار پردازش برنامه کمتر می شود.

حالا اگر دوستان راه حل بهتری دارند لطفا نظرشان را اعلام کنند.ممنون.
من خودم برنامه پست بالا (پست #7) رو تست نکردم اما فکر میکنم دقیقا همون چیزی باشه که شما میخواین.