<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Dante's blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/danteg/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/danteg/feed.xml</link>
    <description>Tester by day, teacher by night, and learning a bit more each day.</description>
    <lastBuildDate>Tue, 16 Apr 2019 04:59:07 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>The next page!</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/the-next-page</link>
      <pubDate>Fri, 10 Jul 2009 14:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2009/07/10/the-next-page/</guid>
      <description><![CDATA[Well, the link isn't QUITE active yet, but if you go to...]]></description>
      <content:encoded><![CDATA[<P>Well, the link isn't QUITE active yet, but if you go to <A href="https://expression.microsoft.com/en-us/dd565875.aspx">https://expression.microsoft.com/en-us/dd565875.aspx</A>&nbsp;you will see the Overview information for Blend 3, and there's a link to download the Blend 3 RC. Now, at *THIS* particular moment, it doesn't seem like it's up there, but the link on that page should go live very shortly.</P>
<P>I've been with the team for 6 and a half years now, and Blend continues to be something I'm very passionate about. To be completely honest, since I wasn't a big Silverlight fanatic, the jump from Blend v1 to Blend v2 didn't feel like a huge jump. Yes, there were TONS of under-the-cover changes that went into the product, so it could support Silverlight and things like that... but the jump from v2 to v3 is TREMENDOUS. Sketchflow is awesome. Silverlight support is awesome. Behaviors are awesome. Sample Data is awesome. I can go on for days, believe me. (In fact, if you look at all the training classes and things I've done internally, I *HAVE* gone on for days).</P>
<P>Grab it. Check it out. Let me know what you think.</P>
<P>Time to change the world. Again :).</P>]]></content:encoded>
    </item>
    <item>
      <title>The longevity of a console</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/the-longevity-of-a-console</link>
      <pubDate>Wed, 01 Jul 2009 18:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2009/07/01/the-longevity-of-a-console/</guid>
      <description><![CDATA[I am very passionate about Blend, there's no question there. But, I'm also a gamer... both board...]]></description>
      <content:encoded><![CDATA[<P>I am very passionate about Blend, there's no question there. But, I'm also a gamer... both board games and computer (PC/Console) games.I was having a conversation with a good friend yesterday, and the more I think about it, the more I just can't accept his argument. Please keep in mind that these are *MY* opinions, and don't reflect the opinions of Microsoft. Everything here is also based on publicly released and announced information, and has absolutely no information that isn't available to everyone else. I don't have some secret inside contact within XBox operations who's feeding me information... it's just the result of, what I thought, was a pretty interesting conversation.<BR><BR><A class="" name=cutid1></A>So, the start of the conversation was about the XBox 360. Recently (I believe it was at E3), Microsoft said that they still see another good 5 years in the existing console, so there are no plans for another XBox until the 2014-2015 time frame.<BR><BR>My comment is that this is great. I would be ecstatic to have another five years in the hardware we've already bought. Besides, since we have two entertainment centers, we have TWO Xboxes, and I'm not in a huge hurry to replace them both.<BR><BR>This is where my friend (who I will call X) disagrees. His comment is that Microsoft should be persuing the enthusiast crowd more heavily. The PC Gaming crowd, which is getting more and more alienated, since more people are developing for consoles, are being forced to move to the consoles. Subsequently, they want the BEST graphics, the BEST sound, and everything like that. So, they're not going to want to move to a new console that's based on 3-4 year old technology.<BR><BR>X asserts that most 'serious' PC gamers upgrade their PC hardware on a once-a-year or once-every-two-year schedule. These gamers want a new console, so everything looks as good as it does on their $2000+ PCs, and if we want to entice them, which we certainly should, we need to make sure that our console is up to date with the biggest, strongest hardware to look it's absolute best.<BR><BR>This is where I disagree, for a handful of reasons...<BR><BR>1. The enthusiast crowd is an interesting crowd, but thanks to the advent of the Wii, a new crowd is getting into gaming. This is the crowd that likes casual games that they can pay $10-$15 for, pick up and play, and run with. The XBox 360 and the Live Arcade is VERY enticing to this crowd. We don't need new hardware to play games like Geometry Wars or Uno. The existing hardware is an excellent solution for these folks.<BR><BR>2. Microsoft loses money on every XBox they make, and recovers that money in accessories and gaming licenses. This is simply a fact. And, let's be honest, the 360 wasn't the smoothest launch ever (My wife is on her third XBox now, and I worry that this one won't last too long either). As time goes on, the amount MS loses on each box decreases as the cost of the parts goes down. Why would we reboot that loss amount when the current console still has life in it?<BR><BR>3. We are in an economy with the highest unemployment in a VERY long time. If, as a bread winner in a family, I had $400 to spend on our entertainment, would I rather buy a new console, and possibly not even have enough money for a game for said console, or would I use that $400 to buy about 6 new games? I firmly believe that the percentage of Americans, right now, who could go out to the store and drop $400 without having to think about it for a few minutes, is pretty low.<BR><BR>4. The console market is *NOT* a market that can keep up with computers. Period. Let's say, for the sake of argument, that the XBox 360-II was announced. We'd end up sending out development kits to various studios, who would know the expected specs of the machine. Now, let's release the 360-II to the market 6 months later. How many of those initial games would really be worth playing? They may have started development sooner, but let's face it... the developers don't know the tricks to make the 360-II really sing the way they can with the 360 today. So, those first wave of games are going to be... meh. Now, let's release the 360-II to the market 2 years later instead of 6 months. Developers have time to make some better games, but now the hardware is 2 years old! The people who upgrade their PC on a once-every-two-years model are already talking about a console that's on par with their LAST generation.<BR><BR>5. And... let's take a look at games right now. How many games out there are people buying based on their graphics? Sure, good graphics are a good selling point, but I'm going to go back to an old argument here, that the technology is not what makes better games. It's game DESIGN. The 360 is plenty strong enough for sophisticated and in-depth games. Don't believe me, check out GTA or Resident Evil 5. Gears of War II has awesome graphics and might have pushed the console further then anyone else did, but everyone says that the gameplay and storyline were lackluster (Although, I enjoyed the daylights out of the game). Stop spending time trying to make the graphics look awesome, and make us a game that's fun, immersive and things like that. Case in point, I was reading an article on IGN about RPGs, and they said that the only RPG that's exclusive to the PS3 that's really worth getting excited about is Valkyria Chronicles. That's not a game that pushed their hardware too hard... from a technical standpoint, it didn't really do much that you couldn't have done on a PS2 or original XBox, aside from more Polygons. But, the GAMEPLAY was what drew you in. Which would you rather have... a pretty game or a good one?<BR><BR>So, considering all of this, and thinking about this from a strategic point... let's say you're the Microsoft exec in charge of making the call...<BR><BR>Do you invest in new technologies that extend the longevity of your console...<BR>&gt;&gt; A console that many development houses are getting DAMNED good at coding against<BR>&gt;&gt; A console that is currently dominating the market, without any strong competition (In my less then humble opinion, Sony is not really a competitor, and Nintendo is a different market segment)<BR>&gt;&gt; A console that is having a lower and lower cost every day as the components get cheaper<BR>&gt;&gt; A console with a damned impressive games library<BR><BR>Or, do you spend the time making a new console...<BR>&gt;&gt; A new console that new developers are going to have to learn how to make it sing<BR>&gt;&gt; A new hardware model, especially after you finally got your existing console working reliably (for the most part)<BR>&gt;&gt; A console that will either require backward compatibility (more work), or not (reducing your game library, and piss off your faithful audience)<BR>&gt;&gt; A console that will have technical capabilities that are at least one generation behind current PCs<BR><BR>To be honest, as I type this out, it almost becomes a shame that we have to rev our consoles every couple years. Because, every couple years, we have to start spending our development dollars on learning the new technology, and less dollars on good, sophisticated and immersive game play. I would argue that the BEST games come out a couple years after one console has come out, when developers know the box and focus on the game, but before the next console comes into play, when the developers stop thinking about this console and start looking ahead to the next.<BR><BR>Viva la 360... </P>]]></content:encoded>
    </item>
    <item>
      <title>Working with Drawing Brushes</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/working-with-drawing-brushes</link>
      <pubDate>Tue, 30 Jun 2009 13:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2009/06/30/working-with-drawing-brushes/</guid>
      <description><![CDATA[Ok folks, I've got a few minutes, and I've been seeing some discussion on our internal lists about...]]></description>
      <content:encoded><![CDATA[<P>Ok folks, I've got a few minutes, and I've been seeing some discussion on our internal lists about Drawing Brushes, how to use them, what they're good for, etc... Sounds like a good time for a Blog post.</P>
<P>First off, what is a DrawingBrush? It's one of the three kinds of TileBrushes that WPF recognizes (along with ImageBrush and VisualBrush). Simply put, it allows you to use a Drawing as a brush, to use on any arbitrary shape.</P>
<P>So, what's a Drawing? A Drawing is simply a set of Visual Elements. You can use pretty much any visuals, rectangles, buttons, Images, etc... but once they become a Drawing, they are no longer interactive. In other words, you can use a Button in a Drawing, but it becomes a 'picture' of a Button, not a real button that can take events, rollover effects, etc... A Drawing is also static. You can't really change it after the fact (Ok, you MAY be able to do it withing code, but I've never tried that).</P>
<P>And, well, since Blend is my area of expertise, I'll demonstrate how to do it with Blend.</P>
<P>(Advance warning... as of right now, Silverlight doesn't support Drawing Brushes, so until they do, this post is only for the WPF crowd, but since we keep seeing more and more of WPF's capabilities moved into Silverlight, it wouldn't surprise me to see DrawingBrushes over there eventually. Also, no, I don't know of any specific plans to move DrawingBrush into Silverlight, and it's possible they never will... I can't tell the future, and I'm not actually on the Silverlight product team).</P>
<P>So, go ahead and fire up Blend and create a WPF Project.</P>
<P>Using the Rectangle Tool, create a rectangle that is 200x100 pixels. Remove the Stroke and set the Fill to a 50% Alpha Red. (#7FFF0000). </P>
<P>Copy and Paste that rectangle, and place the new rectangle adjacent to the first, so it looks like you have a square. Set the Fill of the new Rectangle to have a Fill of 50% Alpha White (#7FFFFFFF).</P>
<P>You should have something like what I'm showing here:</P>
<P><IMG src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/18/HalfRects.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809818/original.aspx" mce_src="https://blogs.msdn.com/photos/danteg/images/9809818/original.aspx"></P>
<P>Ok, now group those two rectangles into a Canvas. (You can do Grid too, if you prefer. It really doesn't matter).</P>
<P>Copy and Paste the Canvas, then rotate it 90 degrees. You should start to get an idea of the effect we're looking for here. (Anyone want to go out for pizza?)</P>
<P><IMG title="Ready to convert to DrawingBrush" style="WIDTH: 262px; HEIGHT: 265px" height=265 alt="Ready to convert to DrawingBrush" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/20/Rects2.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809820/original.aspx" width=262 mce_src="https://blogs.msdn.com/photos/danteg/images/9809820/original.aspx"></P>
<P>To create a DrawingBrush, you need a single base element, and Blend will take all the children and move them into the DrawingBrush for you. At the moment, the two Canvas elements are siblings, and their only parent is the LayoutRoot, which isn't going to work. So, group the two Canvas elements into another Canvas. The visual tree should look like this:</P>
<P>&nbsp;<IMG title="Visual Tree" style="WIDTH: 170px; HEIGHT: 182px" height=182 alt="Visual Tree" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/21/VisualTree.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809821/original.aspx" width=170 mce_src="https://blogs.msdn.com/photos/danteg/images/9809821/original.aspx"></P>
<P>Now, select that base Canvas (the one I have selected in the image above), and in the Tools Menu, select "Make Brush Resource" and "Make Drawing Brush". You're going to get the "Create Resource" dialog, since TileBrushes are handled, by Blend, as resources. Go ahead and set the name and scope to whatever you want and hit Ok.</P>
<P>If it looks like nothing happened, that's Ok. What it did was copy all of the contents of the selected Rectangle and create a Drawing out of them, and create a resource for you. If you don't believe me, switch over to the Resources pane, and look for the Drawing Brush.</P>
<P>In fact, now, we don't even need the original canvas any more, so go ahead and delete it.</P>
<P>Now draw a nice big rectangle (or you could even use your LayoutRoot, if you wanted to). </P>
<P>Go to the Property Inspector, and set the Fill to the new DrawingBrush. It should paint your rectangle with our red cross hatch. Grab the BrushTransform tool, and your rectangle's corner adorners will show up, just as if you were going to resize it. However, when you grab the bottom right adorner and drag it up, you'll see that you're resizing the BRUSH, and not the whole rectangle. That's exactly what you want. In the Image below, I've given my rectangle a thick, black stroke, so you can see that I've resized the FILL, and not the whole rectangle.</P>
<P><IMG src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/31/ResizedBrush.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809831/original.aspx" mce_src="https://blogs.msdn.com/photos/danteg/images/9809831/original.aspx"></P>
<P>You'll also notice that as soon as you do this, you'll break the connection from the DrawingBrush resource. That's Ok. The Resource is of the two rectangles at a specific size, and in this case, we want to have our brush tile for us.</P>
<P>The final step is to set the TileMode on the Fill to Tile. You can also use the BrushTransform tool to mess with the Brush a bit more... maybe rotate it or give it a skew, and you'll get something like this:</P>
<P><IMG src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/36/Tablecloth.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809836/original.aspx" mce_src="https://blogs.msdn.com/photos/danteg/images/9809836/original.aspx"></P>
<P>There you have it. You can continue to experiment... try taking the Stroke off the rectangle you just made, and convert *IT* into a Drawing Brush, and reuse it. Maybe try with a FlipXY, and you can get wild pretty quickly. Here's a quick example of something I threw together using two rectangles and an ellipse, and just keep reusing the "Make Drawing Brush" command with the Brush Transform tool.</P>
<P><IMG src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/09/80/98/48/Capture.PNG" original-url="https://blogs.msdn.com/photos/danteg/images/9809848/original.aspx" mce_src="https://blogs.msdn.com/photos/danteg/images/9809848/original.aspx"></P>
<P>Now, a&nbsp;feature that some folks probably don't know about, is that you can actually edit a DrawingBrush after the fact. To do so, follow these instructions:</P>
<P>Switch to the Resources pane.</P>
<P>Drag the DrawingBrush that you want to edit to the artboard. You'll get a context menu as normal, but there's an option to "Copy DrawingBrush to Canvas". When you do this, you'll get a Canvas with your DrawingBrush exactly as it was before you made it into a DrawingBrush at the beginning.</P>
<P>Go ahead and make any changes you want. (Maybe if you were following the steps here, you'll want to change the 50% white rectangle to a completely empty rectangle, which will change the visuals slightly.</P>
<P>When you're done, right click the BASE canvas that was created, in the Timeline, and you'll find commands for "Move into Source DrawingBrush" or "Copy into Source DrawingBrush". If you choose Move, the canvas that was created will be destroyed, but the information will be moved into your resource. If you choose Copy, it will update the resource, but not delete your Canvas. This latter option is helpful if you just want tweak your brush, see how it looks, and so on. </P>
<P>Remember, though, that as soon as you used the Brush Transform tool, it broke the resource connection, so if you followed THESE steps, you're not going to see it update immediately in the full tablecloth, but you should be able to take the updated DrawingBrush and go through the last steps pretty easily.</P>
<P>Have fun with it!</P>]]></content:encoded>
    </item>
    <item>
      <title>Cre8 and ZAAZ</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/cre8-and-zaaz</link>
      <pubDate>Wed, 20 May 2009 16:21:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2009/05/20/cre8-and-zaaz/</guid>
      <description><![CDATA[This is particularly overdue, but now that I've been featured on the Expression community site, I...]]></description>
      <content:encoded><![CDATA[<P>This is particularly overdue, but now that I've been featured on the Expression community site, I really need to get back to posting again :).</P>
<P>Last month&nbsp;ago, I got the opportunity to present at the <A class="" href="https://cre8summit.com/" target=_blank mce_href="https://cre8summit.com">Cre8 summit</A> in Orlando. I gave two presentations, one on Sketchflow in Expression Blend and one on Blend in general. I was also given the chance to give a keynote during lunch on the second day to show off Sketchflow.</P>
<P>I have to say, that this was one of the most nerve wracking things I've done, speaking to a community of Designers who are still only starting to look at Microsoft products seriously for Web Design. Every eye was on me, and I'm quite happy with how Blend behaved for me. I had plenty of folks compliment the speech, and they were shocked when they heard it was my first.</P>
<P>Blend is really starting to take a serious turn toward being a real competitor. I can feel that by the questions I get asked when I'm talking to folks. We're getting less of the "So, what is this all about?" questions, and more people asking about specifics like Silverlight penetration and the relative complexities between making a prototype in Sketchflow versus working in Visio or Powerpoint. It's building a lot more excitement, and that's just awesome to be a part of.</P>
<P>Recently, I also got a chance to go visit <A class="" href="https://zaaz.com/" target=_blank mce_href="https://zaaz.com">ZAAZ</A> here in Seattle. These are folks who do both Silverlight and Flash development, but they're looking at Sketchflow for doing prototypes in either environment. The most priceless moment was when I was showing off Behaviors in Sketchflow, and one of the designers looked up and said "That f***ing rocks!" It's one thing to work six years on a product, and know in your heart how great it is, and how much it's going to change the landscape, but to have someone looking at it for the first time put it into words... it's a real thrill.</P>
<P>We're doing more internal training classes. More folks are getting interested, and the momentum is really building. I can't wait to unleash this one.</P>
<P>And yes, I'm going to get back on the technical tricks very soon. I've been getting some good questions on DrawingBrush, and there's some functionality that isn't as discoverable as I'd like.</P>]]></content:encoded>
    </item>
    <item>
      <title>A Silverlight TextBlock with Tracking? Surely you jest!</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/a-silverlight-textblock-with-tracking-surely-you-jest</link>
      <pubDate>Fri, 27 Feb 2009 15:02:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2009/02/27/a-silverlight-textblock-with-tracking-surely-you-jest/</guid>
      <description><![CDATA[Well, I know it’s been a while since I’ve posted… although I’m going to be paying a LOT more...]]></description>
      <content:encoded><![CDATA[<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Well, I know it’s been a while since I’ve posted… although I’m going to be paying a LOT more attention to this moving forward. I’m hoping though that my first post back will be worth it.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>We’ve been talking a lot to designers about what they want, and one thing I keep hearing is a desire for Tracking and Kerning. Currently, Silverlight doesn’t really support those, and there really isn’t an easy way to do it.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>So, on the bus this morning, I started thinking, and this is what I came up with. As always, feel free to use any code here that you like, but use at your own risk. I’m certainly up for hearing possible improvements on it. Right now, this only does Tracking, but I’m trying to figure out how to do the kerning as well.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>So, naturally, I’m doing this in Blend (not a huge surprise), but I want to do this in Silverlight. So, I’m creating a new Silverlight project, and I’m going to be creating a custom control. Start off by drawing a TextBlock, selecting it, and choose “Make User Control”. Blend will ask you for a name, and I chose “KerningTextBlock”.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Here’s my strategy. I’m going to use a StackPanel to take care of lining up all my characters, and create TextBlocks for EACH character. Then, set the padding on those TextBlocks to increase the space uniformly between consecutive characters.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>So, get rid of the TextBlock that’s already there, and drop in a StackPanel. Rename that StackPanel since we’re going to be interacting with it in code. I named it “TextDisplay”, since that made sense to me. Also, set the Width and Height to Auto and set the Orientation to Horizontal. </FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Cool, now I want to create two DependencyProperties on our control, and that means code. So, open up the Solution in VS, and let’s get cracking. I want to implement “ActualText” as a string, so I can set it in one place, and have the StackPanel create it’s TextBlocks, and then a “Tracking” as a double that I can set and see the results.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>First, the ActualText:</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">public</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: #2b91af">DependencyProperty</SPAN> ActualTextProperty = <SPAN style="COLOR: #2b91af">DependencyProperty</SPAN>.Register(<SPAN style="COLOR: #a31515">"ActualText"</SPAN>, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: blue">string</SPAN>), <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>), <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">PropertyMetadata</SPAN>(ActualTextValueChanged));<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">public</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">string</SPAN> ActualText<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">get<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: blue">string</SPAN>)GetValue(ActualTextProperty);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">set<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SetValue(ActualTextProperty, <SPAN style="COLOR: blue">value</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">void</SPAN> ActualTextValueChanged(<SPAN style="COLOR: #2b91af">DependencyObject</SPAN> caller, <SPAN style="COLOR: #2b91af">DependencyPropertyChangedEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>This is all pretty much “boilerplate” code. I can use “ActualText” to get and set the property, and every time it changes, ActualTextValueChanged will get called. I’ll use that later to update the contents of my StackPanel.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Next, let’s go ahead and get Tracking:</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">public</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: #2b91af">DependencyProperty</SPAN> TrackingProperty = <SPAN style="COLOR: #2b91af">DependencyProperty</SPAN>.Register(<SPAN style="COLOR: #a31515">"Tracking"</SPAN>, <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: blue">double</SPAN>), <SPAN style="COLOR: blue">typeof</SPAN>(<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>), <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">PropertyMetadata</SPAN>(TrackingValueChanged));<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">public</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">double</SPAN> Tracking<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">get<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">return</SPAN> (<SPAN style="COLOR: blue">double</SPAN>)GetValue(TrackingProperty);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">set<o:p></o:p></SPAN></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>SetValue(TrackingProperty, <SPAN style="COLOR: blue">value</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><o:p><FONT face=Calibri size=3>&nbsp;</FONT></o:p></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">void</SPAN> TrackingValueChanged(<SPAN style="COLOR: #2b91af">DependencyObject</SPAN> caller, <SPAN style="COLOR: #2b91af">DependencyPropertyChangedEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>All right, we’ve got our DPs, now let’s hook them up. For starters, let’s do the ActualText. Whenever it gets changed, we want to clear out the children of the TextDisplay StackPanel, and add new TextBlocks for each character. Here’s the code, and I’ll go through it after:</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">void</SPAN> ActualTextValueChanged(<SPAN style="COLOR: #2b91af">DependencyObject</SPAN> caller, <SPAN style="COLOR: #2b91af">DependencyPropertyChangedEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">StackPanel</SPAN> textDisplay = ((<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>)caller).TextDisplay;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>textDisplay.Children.Clear();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">foreach</SPAN> (<SPAN style="COLOR: blue">char</SPAN> thisChar <SPAN style="COLOR: blue">in</SPAN> e.NewValue.ToString().ToCharArray())<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">TextBlock</SPAN> newTextBlock = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">TextBlock</SPAN>();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>newTextBlock.Text = thisChar.ToString();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>newTextBlock.Padding = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">Thickness</SPAN>(0, 0, ((<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>)caller).Tracking, 0);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>textDisplay.Children.Add(newTextBlock);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>So, what am I doing here? First, I’m grabbing the TextDisplay control. Since the method is static, I can’t simply go to “this.TextDisplay”. But, “caller” is the my KerningTextBlock, and all I need to do is cast it to KerningTextBlock and get my control. </FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Once I’ve got the TextDisplay, I’m going to empty it, with the Children.Clear command.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Finally, I’m going to iterate through each character in the new value, and create a new TextBlock for it. Those TextBlocks are going to get the character as their text, and set the Padding on it to my Tracking property. If you follow the logic, let’s say ActualText is “Dante” and Tracking is 4.0. We clear out the TextDisplay StackPanel, so it’s empty. We then create a TextBlock with only the letter “D”, and give it a 4 pixel padding (to the right). We then add it to the TextDisplay, and continue on with the next letter. We move on to the “a”, add the TextBlock, and so on.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>I realize that this could be optimized to only add additional TextBlocks as needed, and changing the text on the characters instead of destroying and recreating them, but I wanted to start simple. When the handler is called, the “e” argument contains both the OldValue and the NewValue, so writing an optimizer wouldn’t be impossible.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>So, if I wanted to, I could just tell the Tracking property to call the same method as ActualText. But, I decided that I wanted to clean it up just a bit.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">void</SPAN> TrackingValueChanged(<SPAN style="COLOR: #2b91af">DependencyObject</SPAN> caller, <SPAN style="COLOR: #2b91af">DependencyPropertyChangedEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">StackPanel</SPAN> textDisplay = ((<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>)caller).TextDisplay;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">foreach</SPAN> (<SPAN style="COLOR: #2b91af">UIElement</SPAN> thisCharacter <SPAN style="COLOR: blue">in</SPAN> textDisplay.Children)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>((<SPAN style="COLOR: #2b91af">TextBlock</SPAN>)thisCharacter).Padding = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">Thickness</SPAN>(0, 0, ((<SPAN style="COLOR: #2b91af">KerningTextBlock</SPAN>)caller).Tracking, 0);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: normal; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><SPAN style="FONT-SIZE: 10pt; LINE-HEIGHT: 115%; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}</SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>In this case, we’re just iterating through all of the children and resetting the padding. Much less destructive then going through and destroying all the children and rebuilding them every time.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>The cool part about all of this is that you can set properties like the Foreground or FontFamily on the UserControl, and they end up getting inherited. So, once you’ve put all this in, rebuild the project in Blend, and instantiate one of our controls in Blend.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Once you’ve got it in Blend, go down to the Misc category, and you’ll see that both Tracking and ActualText show up as properties. You can set them there and see the effects immediately.<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>Plus, like I said, go ahead and change the Foreground, Font Family, Size, etc… and they’ll update immediately.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>I don’t know how to make Blend think that the control is a Text control, so F2 isn’t going to work like a normal TextBlock, but the concept is there.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT face=Calibri size=3>Now, the part that I’m trying to figure out, is a good way to do the Kerning. Tracking is easy since it’s a uniform spacing between all the characters, but to be able to adjust the positions of individual pairs of characters would be cool. It would be even cooler to automatically detect it, and since you technically can get the geometry of text, it SHOULD be calculatable, but making that performant may be tricky.</FONT></P>
<P class=MsoNormal style="MARGIN: 0in 0in 10pt"><FONT size=3><FONT face=Calibri>Well, hope ya’ll enjoy </FONT><SPAN style="FONT-FAMILY: Wingdings; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-char-type: symbol; mso-symbol-font-family: Wingdings"><SPAN style="mso-char-type: symbol; mso-symbol-font-family: Wingdings">J</SPAN></SPAN><FONT face=Calibri>.</FONT></FONT></P>]]></content:encoded>
    </item>
    <item>
      <title>Featured!</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/featured</link>
      <pubDate>Mon, 03 Mar 2008 11:35:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2008/03/03/featured/</guid>
      <description><![CDATA[Well, I just had it pointed out to me, that my blog is now listed on...]]></description>
      <content:encoded><![CDATA[<P>Well, I just had it pointed out to me, that my blog is now listed on <A href="https://expression.microsoft.com/">https://expression.microsoft.com</A>. I'm actually pretty excited to see myself up there. It does, however, make me realize that I should spend a little time sprucing up the look of my blog.</P>
<P>The current theme is something like "Fire", which I chose because of my love for the elements. You can figure it out... a thought of 'hot software' and the like. But, I'm not saying that Blend isn't 'hot' any more... just that I need to figure out a new 'feel' for my blog.</P>
<P>So, if it seems to change a couple times in the near future, it's just me getting a feel for new looks and such. I will continue to post new thoughts and ideas as I go along. Now that the big thing I was working on (which, naturally, I can't say anything about yet), I should have some more time to play and find new things out. I've been experimenting with font embedding and custom characters, and that should be a pretty cool post coming soon!</P>]]></content:encoded>
    </item>
    <item>
      <title>Moving objects around interactively</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/moving-objects-around-interactively</link>
      <pubDate>Thu, 21 Feb 2008 17:08:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2008/02/21/moving-objects-around-interactively/</guid>
      <description><![CDATA[I was playing around with Blend today, and decided that I wanted to write a function to allow my...]]></description>
      <content:encoded><![CDATA[<P>I was playing around with Blend today, and decided that I wanted to write a function to allow my user to drag the shapes around on my artboard. Granted, this could use a bit of polish, since there are some tweaks that would make it a bit better, but the overall sense should work.</P>
<P>For starters, we need to add a couple private variables to our Window... so I added these three lines:</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: #2b91af">Point</SPAN> initialDragPoint = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">Point</SPAN>(0, 0);<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: #2b91af">Point</SPAN> currentDragPoint = <SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">Point</SPAN>(0, 0);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">bool</SPAN> dragging = <SPAN style="COLOR: blue">false</SPAN>;</SPAN><o:p></o:p></P>
<P>My naming may not be the best, but what I'm setting up here is to keep track of where I clicked the mouse on my object, and for any mouse event, where I am now. I'm also setting up a boolean flag, just to make the code a bit cleaner.</P>
<P>Now, I've already opened Blend, and created a Rectangle. Also, since I don't really want/need all of the layout power of the Grid, I've changed the layout type of my root element to a Canvas. You COULD do this whole thing with RenderTransforms, but in this case, I think that's just more hassle then it's worth.</P>
<P>We need to hook up three events... MouseDown, MouseMove and MouseUp. We'll start with MouseDown...</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">void</SPAN> StartMove(<SPAN style="COLOR: blue">object</SPAN> sender, System.Windows.Input.<SPAN style="COLOR: #2b91af">MouseButtonEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">if</SPAN> (!<SPAN style="COLOR: blue">this</SPAN>.dragging)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.initialDragPoint = e.GetPosition(<SPAN style="COLOR: blue">this</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.dragging = <SPAN style="COLOR: blue">true</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}<o:p></o:p></SPAN></P>
<P>Ok, this method won't do a whole heck of a lot, but what it does is remember the point where the mouse came down, then swap the flag to remember that we're now moving. You'll want to hook this event up to the "MouseDown" event on your shape(s) that you want to allow the user to move.</P>
<P>Next, we'll do MouseUp (which is when the user releases the mouse button).</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">void</SPAN> EndMove(<SPAN style="COLOR: blue">object</SPAN> sender, System.Windows.Input.<SPAN style="COLOR: #2b91af">MouseEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: blue">this</SPAN>.dragging)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.dragging = <SPAN style="COLOR: blue">false</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}<o:p></o:p></SPAN></P>
<P>Again, another simple one... all we do is tell our system that we're done dragging when the user lets go of the mouse button. Finally, the workhorse... MouseMove.</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"> <SPAN style="COLOR: blue">void</SPAN> Moving(<SPAN style="COLOR: blue">object</SPAN> sender, System.Windows.Input.<SPAN style="COLOR: #2b91af">MouseEventArgs</SPAN> e)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: blue">this</SPAN>.dragging)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.currentDragPoint = e.GetPosition(<SPAN style="COLOR: blue">this</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Vector</SPAN> dragVector = <SPAN style="COLOR: blue">this</SPAN>.currentDragPoint - <SPAN style="COLOR: blue">this</SPAN>.initialDragPoint;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">FrameworkElement</SPAN> actor = sender <SPAN style="COLOR: blue">as</SPAN> <SPAN style="COLOR: #2b91af">FrameworkElement</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">double</SPAN> curLeft = (<SPAN style="COLOR: blue">double</SPAN>)actor.GetValue(<SPAN style="COLOR: #2b91af">Canvas</SPAN>.LeftProperty);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">double</SPAN> curTop = (<SPAN style="COLOR: blue">double</SPAN>)actor.GetValue(<SPAN style="COLOR: #2b91af">Canvas</SPAN>.TopProperty);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>curLeft += dragVector.X;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>curTop += dragVector.Y;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>actor.SetValue(<SPAN style="COLOR: #2b91af">Canvas</SPAN>.LeftProperty, curLeft);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>actor.SetValue(<SPAN style="COLOR: #2b91af">Canvas</SPAN>.TopProperty, curTop);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.initialDragPoint = <SPAN style="COLOR: blue">this</SPAN>.currentDragPoint;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes; mso-bidi-language: TH">}<o:p></o:p></SPAN></P>
<P>Let's look at it piece by piece.</P>
<P>First, obviously, we only want to do something if we're currently dragging. So, we gate the whole method to only act if this.dragging is true.</P>
<P>Next, we figure out where the mouse currently is. e.GetPosition(this) does that for me. For the record, the 'this' as an argument just says that I want the point relative to the window. Since I used (this) in MouseDown as well, both of my points will be in the same scale.</P>
<P>To see how this works, let's say that when we did the MouseDown, we were 100 pixels down and 100 pixels to the right of the top left of our window. Then, when we got the MouseUp, we were 120 pixels down and 120 pixels to the right. So, this.initialDragPoint would be (100,100). The e.GetPosition(this) sets the currentDragPoint to (120,120).</P>
<P>The next step is to calculate our dragging Vector. We want our rectangle to move down and to the right, so the calculation is easy... Now, I could have used a Point just as easily, but I tend to think of this as an actual movement vector, so I used the Vector class instead. dragVector gets set to (120-100, 120-100) or (20,20), which is the movement we want on our rectangle.</P>
<P>Next, I need to get the actor (or the shape that my user is moving), and I need it as a FrameworkElement. By casting it to a Framework element, this same code would work for anything... a Grid with a bunch of elements in it... a single rectangle... pretty much anything.</P>
<P>Then, I just use GetValue to get the current Left and Top (see why I wanted to use a Canvas), adjust them by the dragVector, and then set those values.</P>
<P>Finally, the last thing I need to do, is set THIS point as my new base point, so that the new drag is relative to here. Imagine if I hadn't reset it, and then moved the mouse 20 more pixels to the right. The initial point would be 100,100, but the new dragPoint would be (140,120), so my rectangle, which I already moved 20x20 pixels, would be moved another 40x20 pixels. That's no good. So, updating that base value is important.</P>
<P>Granted, there are still some quirks here... for instance, you could start the drag with the left mouse button, then press the right mouse button while dragging... then releasing EITHER button would drop it. I'm sure there are plenty of refinements... but the point is that this should give everyone a good starting point.</P>]]></content:encoded>
    </item>
    <item>
      <title>MIX '08</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/mix-08</link>
      <pubDate>Wed, 13 Feb 2008 17:28:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2008/02/13/mix-08/</guid>
      <description><![CDATA[Well, it's official, I'm going to be presenting at the MIX convention!
I'm really excited for this,...]]></description>
      <content:encoded><![CDATA[<P><STRIKE>Well, it's official, I'm going to be presenting at the MIX convention!</STRIKE></P>
<P><STRIKE>I'm really excited for this, although it's going to be busy for a little while. We need to do dry runs and such. The tentative title is "Unlocking the Creative Genome", but that title may change.</STRIKE></P>
<P><STRIKE>I don't know how many folks who read my blog will be at MIX, but if you are, please stop by and introduce yourself. I'm also going to be in the Expression Blend sandbox, helping folks out with labs and such. I'll send more information as I get it.</STRIKE></P>
<P>If you're not familiar with the MIX, check out <A href="https://www.visitmix.com/" mce_href="https://www.visitmix.com/">https://www.visitmix.com</A>.</P>
<P>CORRECTION: Due to technical issues, my trip to the MIX has been cancelled. My apologies to anyone who was planning on coming to see me there. :(</P>]]></content:encoded>
    </item>
    <item>
      <title>Getting the 'Vista' minimize with Windowless applications</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/getting-the-vista-minimize-with-windowless-applications</link>
      <pubDate>Wed, 16 Jan 2008 11:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2008/01/16/getting-the-vista-minimize-with-windowless-applications/</guid>
      <description><![CDATA[Here's the problem. Launch Blend, and create a window that has AllowsTransparency set to true (which...]]></description>
      <content:encoded><![CDATA[<P>Here's the problem. Launch Blend, and create a window that has AllowsTransparency set to true (which sets the WindowStyle to None). Looks good, yes? Now, add a button, and in the Click handler, set the WindowState property to Minimized.</P>
<P>Run the application on Vista, and click your minimize button. You'll notice that the window just vanishes! It doesn't get the nice minimize behavior like you'd expect (You know, the animation. Minimize any other app, and you'll see what I mean).</P>
<P>One of my teammates, Brian, was trying to get this to work, and he did some research. Apparently, if you set this.WindowStyle to WindowStyle.SingleBorderWindow, it will minimize correctly. He was pretty excited about this, and brought it to me. I'm not completely sure why it works, because when you restore the window, it's still the "none" WindowStyle, but it does work.</P>
<P>Problem is, if you run the minimize behavior a second time, it fails with an InvalidOperationException, and your app comes crashing down.</P>
<P>We tried resetting the WindowStyle back to None after Minimizing it, but that caused a different InvalidOp.</P>
<P>So, we played with it a bit, and it seems (oddly enough) that if you set the property ONCE after the window has been created, that you get the minimizing behavior. You just can't set it twice.</P>
<P>So, try this method:</P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">private</SPAN><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"> <SPAN style="COLOR: blue">void</SPAN> MinimizeIt(<SPAN style="COLOR: blue">object</SPAN> sender, <SPAN style="COLOR: #2b91af">RoutedEventArgs</SPAN> e)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">if</SPAN> (<SPAN style="COLOR: blue">this</SPAN>.WindowStyle != <SPAN style="COLOR: #2b91af">WindowStyle</SPAN>.SingleBorderWindow)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.WindowStyle = <SPAN style="COLOR: #2b91af">WindowStyle</SPAN>.SingleBorderWindow;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">this</SPAN>.WindowState = <SPAN style="COLOR: #2b91af">WindowState</SPAN>.Minimized;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0in 0in 0pt"><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes">}</SPAN><o:p></o:p></P>
<P>And from our experimentation, this would consistently cause the window to minimize in the "Vista" way, didn't cause a crash, and oddly enough, didn't change the appearance at all. Oddly enough, for grins, I tried putting that line in the Window1.Loaded event handler (Well, without the If statement), and it gives me the InvalidOperation exception.</P>]]></content:encoded>
    </item>
    <item>
      <title>Transparent Windows and how to Resize them</title>
      <link>https://docs.microsoft.com/archive/blogs/danteg/transparent-windows-and-how-to-resize-them</link>
      <pubDate>Wed, 21 Nov 2007 14:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Dante Gagne MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/danteg/2007/11/21/transparent-windows-and-how-to-resize-them/</guid>
      <description><![CDATA[A teammate came to talk to me, because he's working with a semi-transparent window, with no Border,...]]></description>
      <content:encoded><![CDATA[<P>A teammate came to talk to me, because he's working with a semi-transparent window, with no Border, and he wants to be able to resize it. Allowing a user to move, minimize, maximize and close it are easy, but how to resize?</P>
<P>Well, this is actually pretty easy. There is a property on the Window named ResizeMode, and if you set it to "CanResizeWithGrip", then a ResizeGrip control is placed on your window automatically, and if you run the app, it will, correctly, resize your window.</P>
<P>But, the default grip is six small squares arranged in a SE-pointing triangle. And, if you look in Blend, that control isn't actually in the XAML, so there's no way to modify it. You can't even make it transparent to put a customized control 'under' it. And it's magical, in that it you can't possibly get another control on top of it, even with Bring To Front... So, how do you customize the look and feel of that control?</P>
<P>You'll find that you can create a new ResizeGrip control, and place it in the bottom right, but you will find that it will be rendered under this mystical ResizeGrip, so no customization there either...</P>
<P>Under the covers, here's the problem. That ResizeGrip is not 'technically' part of the Window. Just as WPF is about to instantiate the window, it sees that the ResizeMode is set to CanResizeWithGrip, and it creates that grip for you in the SE corner. It simply instantiates the control, sets the properties to show up in the bottom left, and that's it. Unfortunately, this means that you can't modify any of the&nbsp;properties on it, since it's actually created&nbsp;when the Window is Instantiated.</P>
<P>I suppose, if you wanted to, you could, in code, track down that control by looking at the children of the Window, although I'm not even sure it *IS* technically even there.</P>
<P>You could also create your own&nbsp;custom control (probably inherited from Thumb), and implement all your own MouseDown/Up/Move code to do your resizing for you.&nbsp;</P>
<P>Thankfully, here's&nbsp;a better&nbsp;solution. Drop a ResizeGrip somewhere on your document, and edit a copy of the template. But, when the dialog comes up to let you know that you're creating a new Template, click the "Apply To All" radio button, instead of supplying a name. By specifying Apply To All, you're telling WPF that any new controls of this type, unless they specify a new template, should use the template that you're creating at this moment. Go ahead and trick out the ResizeGrip however you want in the Template, then delete the ResizeGrip that you created at the beginning of this process. </P>
<P>Now, you've got a new default ResizeGrip template, so now when WPF instantiates that ResizeGrip, it gets your new default template, and gets the look and feel you want.</P>
<P>The obvious question, now, is that once you've done this, what if you want different ResizeGrips for different areas of your window? I.e. maybe my dialogs that show names have a resize grip with a yellow smiley face, but my dialogs for error messages show a little horned devil.</P>
<P>Two points here... First, when you define your new default template, you can specify the scope. So, if you scope your new template to the Application, then ALL your ResizeGrips will look identical. However, if you scope it to individual windows, those windows can have different templates.</P>
<P>Second, there's nothing stopping you from creating a template whose appearance is a transparent block. Then, you can simply put whatever you want your grip to look like at the bottom right, and the real resize grip will be rendered on top, but since it's transparent, you won't see it... you'll just get the functionality. Of course, if you're going to try this route, make sure your little smiley faces or whatever are laid out in such a way that they'll stay at the bottom right :).</P>
<P>Enjoy!</P>
<P>PS: If folks don't know how to set up moving/close/minimize behavior on transparent windows, give me a shout, and I'll put something here for those scenarios.</P>]]></content:encoded>
    </item>
  </channel>
</rss>