|
Pete O'Hanlon wrote: anonymous functions can be notoriously difficult to unregister
Hi Pete,
I rarely use anonymous functions (I prefer the clarity provided by having a 'proper' method call) but hadn't considered unregistering from an event in that scenario. A good point!
|
|
|
|
|
Pete O'Hanlon wrote: anonymous functions can be notoriously difficult to unregister.
Excellent point !
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
I have gone through all the replies but I am not able to convert the code in the simple understandable format.
I am pasting the the two .cs file below, if someone can help putting it in the simple fashion for all the 3 eventhandler delegates.
1) PuzzleGame.cs
using Mosaic;
namespace WindowsPhonePuzzle
{
public class PieceUpdatedEventArgs : EventArgs
{
public int PieceId { get; set; }
public Point NewPosition { get; set; }
}
public class GameOverEventArgs : EventArgs
{
public int TotalMoves { get; set; }
}
public class PuzzleGame
{
public EventHandler GameStarted;
public EventHandler<PieceUpdatedEventArgs> PieceUpdated;
public EventHandler<GameOverEventArgs> GameOver;
if (this.GameStarted != null)
{
this.GameStarted(this, null);
}
}
if (this.GameOver != null)
{
this.GameOver(this, new GameOverEventArgs { TotalMoves = this.totalMoves });
}
}
}
if (this.PieceUpdated != null)
{
this.PieceUpdated(this, new PieceUpdatedEventArgs {PieceId = pieceId, NewPosition = newPosition});
}
}
}
}
2) PuzzlePage.xaml.cs
<pre lang="c#">
using WindowsPhonePuzzle;
namespace Mosaic
{
public partial class PuzzlePage : PhoneApplicationPage
{
public PuzzlePage()
{
InitializeComponent();
SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
this.game = new PuzzleGame(3);
this.game.GameStarted += delegate
{
this.ResetWinTransition.Begin();
this.StatusPanel.Visibility = Visibility.Visible;
this.TapToContinueTextBlock.Opacity = 0;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
};
this.game.GameOver += delegate
{
this.WinTransition.Begin();
this.TapToContinueTextBlock.Opacity = 1;
this.StatusPanel.Visibility = Visibility.Visible;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
};
this.game.PieceUpdated += delegate(object sender, PieceUpdatedEventArgs args)
{
int pieceSize = ImageSize / this.game.ColsAndRows;
this.AnimatePiece(this.puzzlePieces[args.PieceId], Canvas.LeftProperty, (int)args.NewPosition.X * pieceSize);
this.AnimatePiece(this.puzzlePieces[args.PieceId], Canvas.TopProperty, (int)args.NewPosition.Y * pieceSize);
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
};
this.InitBoard();
}
modified 12-Jul-12 8:40am.
|
|
|
|
|
Sorry, but no.
Nobody is going to wade through that much code and "tidy it up" for you!
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
No Problems at all.
I thought the way quick inputs were provided by all it should be quick to replace 3 calls simple code or just simple pointer for one would be fine.
I just wanted to understand how it will work in simple call then in this twisted fashion.
Thanks to all.
|
|
|
|
|
I have removed all the irrelevant code from modified the post.
Can now someone help in simplyfying it. One is the class file where the event handlers are decalared and other is the actual page file where definition is there <inline> as well call to the inline code is happening from it.
Thanks
|
|
|
|
|
What and where is the problem?
|
|
|
|
|
In puzzlepage.xaml.cs as shown in my modified post, there is code starting with line as shown below.
<pre lang="c#">
this.game.GameStarted += delegate
I want to convert it in the simple form, which I am not able to do.
The code is fine and its working, onlt thing is that to understand the delegate better I want to see how actually its working.
Thanks
|
|
|
|
|
Griff has given you the answer Hope you have got the concept now.
|
|
|
|
|
|
There are only two changes you can really make there: the first is to change from anonymous methods to named methods.
this.game.GameStarted += delegate
{
this.ResetWinTransition.Begin();
this.StatusPanel.Visibility = Visibility.Visible;
this.TapToContinueTextBlock.Opacity = 0;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
}; Becomes
this.game.GameStarted += MyGameStarted;
...
private void MyGameStarted(object sender, EventArgs e)
{
this.ResetWinTransition.Begin();
this.StatusPanel.Visibility = Visibility.Visible;
this.TapToContinueTextBlock.Opacity = 0;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
}; This is a matter largely of style - as I said I prefer named methods, but have a look at the other comments you got before you make your mind up.
The other change looks trivial, and it adds a little code, but it is something I do with all delegates, be they event handlers or not.
if (this.GameStarted != null)
{
this.GameStarted(this, null);
} Becomes
EventHandler eh = GameStarted;
if (eh != null)
{
eh(this, null);
} The only difference is that I read the value once, and action from that value, while your code reads it twice. If the delegate method is removed from the list between the two instructions, your version will get a null reference, while mine won't. That said, it is very,. very unlikely to ever happen, but I prefer to code for the unlikely events as well as the common ones!
As a side note, you don't need to write this so often - I almost never use it, except where a local variable masks the name of the class level version:
private string name;
public string Name {get { return name; } set { name = value; } }
public MyClass(string name)
{
this.name = name;
} The rest of the time there is no conflict, so the clear resolution of name to a class level variable is unneccessary:
Console.WriteLine(this.name); Is identical to:
Console.WriteLine(name); But the latter needs less typing and is quicker to read.
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Thank you sir. I could change code now to simple format.
Really appreciate your help, it has given me lot of insigt into the Delegate concept today.
"A Day is wasted if you have not learned anything new, and today I have learned a lot."
Thanks
|
|
|
|
|
A good sentiment.
And you are welcome!
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
5 to all of the above
|
|
|
|
|
By using += we attach a delegate handler to the appropriate method that needs to be called when the handler is invoked.
In your example, += is used to attach the GameStarted and GameOver handlers to anonymous methods that would be executed when these handlers are invoked.
|
|
|
|
|
please tell me the concept of delegates. I have seen from it from book but didnt get it properly.. what i read is it is a type safe object that can point to another method or multiple method in the application which can be invoked at later time.
|
|
|
|
|
What you have read and understood is actually quite correct.
A delegate is a type that safely encapsulates a method, similar to a function pointer in C and C++. Unlike C function pointers, delegates are object-oriented, type safe, and secure. The type of a delegate is defined by the name of the delegate. A delegate encapsulates a method.
A delegate object is normally constructed by providing the name of the method the delegate will wrap, or with an anonymous Method. Once a delegate is instantiated, a method call made to the delegate will be passed by the delegate to that method. The parameters passed to the delegate by the caller are passed to the method, and the return value, if any, from the method is returned to the caller by the delegate. This is known as invoking the delegate. An instantiated delegate can be invoked as if it were the wrapped method itself.
E.g. In the example below, a delegate (with a string as parameter) is created and then invoked by using the handler.
The handler points to the actual method.
public delegate void Del(string message);
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
Del handler = DelegateMethod;
handler("Hello World");
Note: Text and example taken from http://msdn.microsoft.com/en-us/library/ms173172.aspx[^].
|
|
|
|
|
That's about the size of it!
A delegate is a variable, but instead of having a value that you can add or subtract, the value is the address of a method that you can call.
At it's most basic, a delegate allows you to specify a routine to execute at runtime rather than compile time. This can make code more flexible: a method could print data to a variety of sources without ever needing to know where the data is going, because it just calls the method that the delegate refers to. So as long as all the methods you pass to the delegate operate correctly on the data, you can add a destination without changing the code that does the mechanics of the printing at all.
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
I am going to dare to respond with an emphasis that is a bit at variance with the two other commentators' remarks here (both of whom I regard, personally, as "CodeProject Bacon, prime cut, extra-lean," and respected mentors).
I must, however, on one point, dare to question OG's description of a delegate as a "variable." I don't think that's a helpful way to describe what they are, particularly to those just getting into the concept, even though it's "technically true," on a certain level.
I would describe a delegate as a Type which is a declaration of a signature of an encapsulated Method.
Where "signature" means a specification of the types of expected output Type and inputs (usual list of parameters) that instances of the delegate will, later, "contain."
Numerous instances of the delegate can be created: as long as each new instance of the delegate has assigned to it a method (or an in-line anonymous method is provided, and assigned) whose parameters match the signature of the delegate: you have a "legal" instance of the delegate.
Let's look at a trivial example of using the same delegate more than once:
public delegate int trivialDelegate(int int1, int int2);
public static int AddEm(int int1,int int2)
{
return int1 + int2;
}
public static int DivEm(int int1,int int2)
{
return int1 / int2;
}
public static trivialDelegate lateBoundAdd = AddEm;
public static trivialDelegate lateBoundDiv = DivEm;
public static trivialDelegate lateBoundSub = (int1, int2) => int1 - int2; So, now, somewhere in your code at run-time, you can invoke these late-bound methods:
int addResult = lateBoundAdd(100, 200);
int divResult = lateBoundDiv(1000, 333);
int subResult = lateBoundSub(999, 666); So, what's the big deal about "late-binding:" it means you could change the code in the method that is assigned to delegate, at any time, and add other calls to it, do other things with it, at run-time, as long as your new method assigned to the instance name "obeys" the signature of the delegate's required syntax.
The glyphs you are reading now: are place-holders signifying the total absence of a signature.
|
|
|
|
|
hello guys. Instead of adding tab pages, is there any way I could add my designed and finished forms to a tab control? I have tried this but could not succeed. I have heard this can be done using User Controls but I don't want to use them, and it is really painstaking task too.
Will panels have any kind of role into this scenario? Thanks for any pointer.
This world is going to explode due to international politics, SOON.
modified 12-Jul-12 6:53am.
|
|
|
|
|
You can add a form to a tab page by setting its TopLevel property to false and then using Controls.Add in the normal way. It is a bit strange and you shouldn't do it unless there's a good reason to do so, but it does work. A previous project here at work did this.
If you're just trying to design panels, and they can never be standalone forms, I recommend that you inherit from UserControl not from Form. The VS designer will still allow you to visually design UserControls.
|
|
|
|
|
BobJanova wrote: You can add a form to a tab page by setting its TopLevel property to false and then using Controls.Add in the normal way.
Hi. I did that. It adds the form to the tab control. But the controls on the form don;t show. Why do these controls go away?
The reason to do so is: I want to have a separate class for each tabpage. If I add controls to tab control, they will remain in the main ( and single ) class. If I could design and implement forms and THEN add them to the tab control, then it will certainly add to my good (and stand-alone) class design.
This world is going to explode due to international politics, SOON.
|
|
|
|
|
Hm, there is some small trick here but I can't remember what it is, sorry. I think our Forms were hosted on a Panel inside the TabPage, try that.
You can have a separate designer by designing a subclass of UserControl or Panel. If it's never a standalone form, there's no reason for it to inherit Form.
|
|
|
|
|
BobJanova wrote: I think our Forms were hosted on a Panel inside the TabPage, try that.
Does that work? Cause panels, themselves, are not stand-alone and need some container (just like tabpages need tab control).
Anyway, I had to play with properties of Form as I saw your first solution on couple of web sites. Here is tricky solution.
TabPage tab1 = tabCtrl.TabPages["TabName"];
Form.TopLevel = false;
Form.FormBorderStyle = FormBorderStyle.None;
Form.Parent = tab1;
Form.Visible = true;
tab1.Controls.Add(Form);
Cheers
This world is going to explode due to international politics, SOON.
|
|
|
|
|
Is anybody aware of any guidelines, issued by Microsoft or any other parties, about exposing a Queue or Queue<T> as a public property on an object? I recall some old guidelines about exposing a generic collection, but I can't find any recent information about that, either.
|
|
|
|
|