Finally something with more code and less markup...actually, a lot less markup. The only object in markup besides the main application window is a Canvas for drawing the rings. There will be no need to create a method akin to "InitializeComponent" this time and I will be able to really focus on C# and .NET without worrying about how to translate from XAML.
Here's the full translation of the XAML for the window:
public class Window1 : Window
{
Canvas MainCanvas;
public Window1()
{
//<window ...="" title="Concentric Rings" width="910" height="512">
this.Title = "Concentric Rings";
this.Width = 910;
this.Height = 512;
//<canvas name="MainCanvas" background="#FFE0E0E0"></canvas>
MainCanvas = new Canvas();
BrushConverter bc = new BrushConverter();
SolidColorBrush brush = bc.ConvertFromString("#FFE0E0E0") as SolidColorBrush;
MainCanvas.Background = brush;
this.Content = MainCanvas;
}
}
That's enough to get the window to show up with a gray canvas. The background was a little tricky. The "Background" property must be assigned a "Brush" type so I knew just setting it equal to the string wouldn't work. I noticed the "BrushConverter" class thanks to Visual Studio's autocomplete feature but I wanted to make sure I used it correctly so I searched the internet and found the perfect example. I also made a note to myself that "Canvas" comes from "System.Windows.Controls" and "BrushConverter" (as well as all other brush/color related stuff) comes from "System.Windows.Media".
All the rest of the code is already written so all I need to do is come to understand it. I want to finish the container before getting the circles to appear.
It is very useful to be able to control how the window looks to the user. Sometimes you want them to be able to resize, sometimes you want to remove the border. For the concentric rings, we want the window to be maximized, without any border or titlebar and without showing the taskbar.
These are the three important lines:
this.WindowState = WindowState.Maximized; this.WindowStyle = WindowStyle.None; this.ResizeMode = ResizeMode.NoResize;
I tried different combinations. Without any of those lines, the window looks like a normal application. By setting "WindowStyle.None", the titlebar (and buttons) disappear but it still has the border so it can be resized. If you keep the window style normal but set "ResizeMode.NoResize", you regain the title bar and still have a border but cannot change the size of the window. It is only with both "WindowStyle.None" and "ResizeMode.NoResize" does the boarder disappear. That's nice, but we want it to be maximized. Set "WindowState.Maximized" and you get a normal looking maximized window. Set "ResizeMode.NoResize" and magically, the taskbar disappears. What if we say it can be resized but get rid of the title bar? It still forces the taskbar away. So if we want it maximized, why go through the trouble of setting "NoResize" if it's not needed to get the look we want? Well, if you "alt-tab" to another program, you can see the taskbar, then you can right click on "Concentric Rings" and, if you set "NoResize", then you won't be able to restore the window, it will always be maximized. I personally think it would be better to have a windowed and fullscreen mode but perhaps that introduces unnecessary complications...I also think it's strange the programmer wants to force the window to stay maximized but set the "Width" and "Height" properties in XAML.
Since the window will be maximized at all times with no buttons or other GUI, it would be nice to offer a way to close the application without resorting to the "alt-tab" trick. For the last part of this part, I'll look at quitting with the "Escape" key.
It's very simple, especially if you've worked with any user interaction before. Just set the event handler for a keypress, check which key, and act appropriately:
public Window1()
{
...
this.KeyDown += new System.Windows.Input.KeyEventHandler(Window1_KeyDown);
...
}
void Window1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Escape)
this.Close();
}
This is very similar to the Calculator.
Next time, I will try to understand the use of:
System.Windows.Threading.DispatcherTimer frameTimer; private int lastTick; private Random rand;
We've done animation without those objects before, so why use them now?
No comments:
Post a Comment