{"id":492,"date":"2014-07-25T11:11:05","date_gmt":"2014-07-25T11:11:05","guid":{"rendered":"http:\/\/www.nikola-breznjak.com\/blog\/?p=492"},"modified":"2015-08-10T07:09:13","modified_gmt":"2015-08-10T07:09:13","slug":"build-a-font-viewer-application-in-wpf-without-writing-any-c-code","status":"publish","type":"post","link":"https:\/\/nikola-breznjak.com\/blog\/codeproject\/build-a-font-viewer-application-in-wpf-without-writing-any-c-code\/","title":{"rendered":"How to build a font viewer application in WPF without writing any C# code"},"content":{"rendered":"<h2><strong>TL;DR<\/strong><\/h2>\n<p>You can <a href=\"https:\/\/github.com\/Hitman666\/FontViewer\">download from Github<\/a> the demo application (zipped exe) or the whole source code project (Visual Studio project solution), or continue reading to see how it was built step by step.<\/p>\n<h2>What is this for an application?<\/h2>\n<p>My version of the FontViewer application as initially designed and developed in the book <a href=\"http:\/\/www.amazon.com\/Sams-Teach-Yourself-WPF-Hours\/dp\/0672329859\">Sams Teach Yourself WPF in 24 Hours<\/a>, with added IntegerUpDown control from <a href=\"https:\/\/wpftoolkit.codeplex.com\/\">Extended.Wpf.Toolkit<\/a> NuGet package (for changing the font size).<\/p>\n<h2>Disclamer<\/h2>\n<p>I&#8217;m in no way affiliated with Amazon or this book, I just think it&#8217;s great, for beginners especially. <a href=\"http:\/\/stackoverflow.com\/questions\/9591\/what-wpf-books-would-you-recommend\">This StackOverflow question<\/a> may be useful if you&#8217;re searching for a good book on learning WPF.<\/p>\n<h2>Let&#8217;s build it step by step<\/h2>\n<p>First, create a new WPF Application project in Visual Studio (File -&gt; New Project) as shown on the image below, and name it FontViewer:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_1.jpg\" rel=\"lightbox[492]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-533\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_1.jpg\" alt=\"FontViewer_1\" width=\"955\" height=\"660\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_1.jpg 955w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_1-300x207.jpg 300w\" sizes=\"auto, (max-width: 955px) 100vw, 955px\" \/><\/a><\/p>\n<h3>Full source code listing<\/h3>\n<p>Now, copy the following\u00a0XAML code in your MainWindow.xaml file (explanation comes after):<\/p>\n<pre class=\"lang:default decode:true\">&lt;Window x:Class=\"FontViewer.MainWindow\"\r\n        xmlns=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\/presentation\"\r\n        xmlns:x=\"http:\/\/schemas.microsoft.com\/winfx\/2006\/xaml\"\r\n        xmlns:xctk=\"http:\/\/schemas.xceed.com\/wpf\/xaml\/toolkit\"\r\n        Title=\"FontViewer\" Height=\"450\" Width=\"600\"&gt;\r\n    \r\n    &lt;DockPanel Margin=\"8\"&gt;\r\n        &lt;Border DockPanel.Dock=\"Top\"\r\n                CornerRadius=\"1\"\r\n                BorderThickness=\"2\"\r\n                BorderBrush=\"Black\"\r\n                Background=\"AliceBlue\"\r\n                Padding=\"8\"\r\n                Margin=\"0 0 0 8\"&gt;\r\n            &lt;TextBlock FontSize=\"14\" TextWrapping=\"Wrap\"&gt;\r\n                &lt;Bold&gt;&lt;Italic&gt;Instructions:&lt;\/Italic&gt;&lt;\/Bold&gt;\r\n                &lt;LineBreak \/&gt;\r\n                \r\n                Select a &lt;Underline&gt;font&lt;\/Underline&gt; to view from the list &lt;Italic&gt;below&lt;\/Italic&gt;.\r\n                &lt;Span FontSize=\"10\"&gt;\r\n                    You can change the text by typing in the region at the bottom.\r\n                &lt;\/Span&gt;\r\n            &lt;\/TextBlock&gt;\r\n        &lt;\/Border&gt;\r\n        \r\n        &lt;ListBox x:Name=\"FontList\" \r\n                 DataContext=\"{x:Static Fonts.SystemFontFamilies}\"\r\n                 DockPanel.Dock=\"Left\" \r\n                 ItemsSource=\"{Binding}\"\r\n                 Width=\"160\"&gt;\r\n            &lt;ListBox.ToolTip&gt;\r\n                &lt;ToolTip&gt;\r\n                    &lt;StackPanel Orientation=\"Horizontal\"&gt;\r\n                        &lt;TextBlock Text=\"{Binding Path=Count, Mode=OneTime}\"\/&gt;\r\n                        &lt;TextBlock Text=\" fonts are installed.\"\/&gt;\r\n                    &lt;\/StackPanel&gt;\r\n                &lt;\/ToolTip&gt;\r\n            &lt;\/ListBox.ToolTip&gt;\r\n        &lt;\/ListBox&gt;\r\n\r\n        &lt;StackPanel Orientation=\"Horizontal\"  \r\n                    HorizontalAlignment=\"Center\" \r\n                    Margin=\"5\"\r\n                    DockPanel.Dock=\"Top\"&gt;\r\n            \r\n            &lt;TextBlock Margin=\"0 0 5 0\"&gt;Font size:&lt;\/TextBlock&gt;\r\n            &lt;xctk:IntegerUpDown x:Name=\"FontSize\"\r\n                                Height=\"20\" \r\n                                Width=\"50\"\r\n                                Increment=\"1\" \r\n                                Value=\"20\"&gt;\r\n            &lt;\/xctk:IntegerUpDown&gt;\r\n        &lt;\/StackPanel&gt;\r\n\r\n        &lt;TextBox x:Name=\"SampleText\"\r\n                 MinLines=\"2\"\r\n                 Margin=\"5\"\r\n                 TextWrapping=\"Wrap\"\r\n                 ToolTip=\"Type here to change the preview text.\"\r\n                 DockPanel.Dock=\"Top\"&gt;\r\n            The quick brown fox jumps over the lazy dog.\r\n        &lt;\/TextBox&gt;\r\n\r\n        &lt;TextBlock Text=\"{Binding ElementName=SampleText, Path=Text}\"\r\n                   FontFamily=\"{Binding ElementName=FontList,Path=SelectedItem}\"\r\n                   FontSize=\"{Binding ElementName=FontSize,Path=Value}\"\r\n                   TextWrapping=\"Wrap\"\r\n                   Margin=\"5\"\/&gt;\r\n    &lt;\/DockPanel&gt;\r\n&lt;\/Window&gt;\r\n<\/pre>\n<h3>Code decomposition<\/h3>\n<p>You can see that our main container is <strong>DockPanel<\/strong>, which is useful when you want to &#8220;dock&#8221; certain elements to the sides (top, bottom, left, right) of the window.<\/p>\n<p>Next comes the <strong>Border<\/strong> element which contains instructions (on how to use the application) written inside the <strong>TextBlock<\/strong> element. If you&#8217;re familiar with CSS, the attributes on the Border element should\u00a0seem natural\u00a0to you. However, one novelty is the <strong>DockPanel.Dock=&#8221;Top&#8221;<\/strong> property which basically tells the Border element to position itself at the top of the parent DockPanel (in which it is contained).<\/p>\n<p>To populate the list of available fonts which are installed on the machine, we&#8217;re using the <strong>ListBox<\/strong> element. It&#8217;s docked to the left, its name variable (by which we can reference it later in the code) is set to\u00a0<strong>FontList<\/strong> (x:Name=&#8221;FontList&#8221;), and most importantly the <strong>ItemSource<\/strong>\u00a0attribute is set to\u00a0<strong>{x:Static Fonts.SystemFontFamilies}<\/strong>\u00a0which basically tells the ListBox that it should display all the items which are returned from the static property SystemFontFamilies provided by\u00a0.NET framework.<\/p>\n<p>After the ListBox comes a <strong>StackPanel<\/strong>\u00a0which by default &#8220;stacks&#8221; elements that it contains one below the other. By using the <strong>Orientation<\/strong>\u00a0property (Orientation=&#8221;Horizontal&#8221;) we can\u00a0make the contained elements align one next to the other.<\/p>\n<h3>Let&#8217;s mix it up a little<\/h3>\n<p>Since we want to have a numeric Up\/Down control as we do in WinForms we will have to download additional component as it doesn&#8217;t\u00a0exist in the standard WPF library. The discussion about this can be found on <a href=\"http:\/\/stackoverflow.com\/questions\/382676\/good-numericupdown-equivalent-in-wpf\">Stack Overflow<\/a>. The solution is to go to Tools -&gt; NuGet Package Manager -&gt; Manage NuGet Packages&#8230; as shown on the illustration below:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_3.jpg\" rel=\"lightbox[492]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-534\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_3-1024x584.jpg\" alt=\"FontViewer_3\" width=\"604\" height=\"344\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_3-1024x584.jpg 1024w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_3-300x171.jpg 300w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_3.jpg 1042w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/a><\/p>\n<p>On the form that shows up after this you have to do a search for\u00a0<strong>Extended.Wpf.Toolkit <\/strong>and Install it:<\/p>\n<p><a href=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_2.jpg\" rel=\"lightbox[492]\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-536\" src=\"http:\/\/www.nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_2.jpg\" alt=\"FontViewer_2\" width=\"900\" height=\"600\" srcset=\"https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_2.jpg 900w, https:\/\/nikola-breznjak.com\/blog\/wp-content\/uploads\/2014\/07\/FontViewer_2-300x200.jpg 300w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/p>\n<p>As stated in the <a href=\"http:\/\/wpftoolkit.codeplex.com\/documentation\">installation instructions<\/a>\u00a0you have to:<\/p>\n<ol style=\"color: #253340;\">\n<li>Add a <strong>using<\/strong> statement (&#8220;<strong>using Xceed.Wpf.Toolkit;<\/strong>&#8221; for most of the controls, &#8220;using Xceed.Wpf.DataGrid;&#8221; for the datagrid control) to the top of <strong>.cs<\/strong> files<strong><br \/>\n<\/strong><\/li>\n<li>Add a new <strong>xmlns<\/strong> (<strong>xmlns:xctk=&#8221;http:\/\/schemas.xceed.com\/wpf\/xaml\/toolkit&#8221;<\/strong> for most of the controls, xmlns:xcdg=&#8221;http:\/\/schemas.xceed.com\/wpf\/xaml\/datagrid&#8221; for the datagrid control) to the top of XAML files<\/li>\n<li>Remember to use the namespace prefix (in the above example, &lt;xctk: &#8230;&gt; or &lt;xcdg: &#8230;&gt;) in the body of your XAML<\/li>\n<\/ol>\n<p>As you can\u00a0see in the full code listing, I added the needed <strong>xmlns<\/strong>\u00a0in MainWindow<strong>.xaml<\/strong>. However, the needed <strong>using<\/strong>\u00a0statement (using using Xceed.Wpf.Toolkit;) has to be\u00a0added\u00a0in the MainWindow<strong>.cs\u00a0<\/strong>(right click on the MainWindow.xaml file and select <strong>View Code<\/strong>) file.<\/p>\n<p>After this installation and proper including is done, you can use the new <strong>IntegerUpDown<\/strong> control in your XAML\u00a0file like this:<\/p>\n<pre class=\"lang:default decode:true\">&lt;xctk:IntegerUpDown x:Name=\"FontSize\"\r\n                    Height=\"20\" \r\n                    Width=\"50\"\r\n                    Increment=\"1\" \r\n                    Value=\"20\"&gt;\r\n&lt;\/xctk:IntegerUpDown&gt;<\/pre>\n<p><strong>Increment<\/strong> attribute tells the control by which amount to increment\/decrement the number which is set by default in <strong>Value<\/strong>\u00a0attribute.<\/p>\n<h3>Let&#8217;s enter some text<\/h3>\n<p>In order for the user to be able to enter some text and then see how\u00a0the text looks like in the particular font, we&#8217;re using the <strong>TextBox<\/strong> element. Most important attribute is the <strong>x:Name<\/strong> (x:Name=&#8221;SampleText&#8221;) because we&#8217;ll use it to reference it in the TextBlock below.<\/p>\n<h3>Show me how the font looks like<\/h3>\n<p>We&#8217;re using the <strong>TextBlock<\/strong> element to show the user how the text which he entered in the TextBox looks like in the font which he selected from the ListBox. Here lies the core of our application as here we&#8217;re setting the so called <strong>Data Binding<\/strong>. We&#8217;re binding\u00a0the <strong>Text<\/strong> attribute of the TextBlock to\u00a0whatever is entered in the TextBox named SampleText (Text=&#8221;{Binding ElementName=SampleText, Path=Text}&#8221;). Next, we&#8217;re binding\u00a0the <strong>FontFamily<\/strong> to the selected item in the ListBox named FontList (FontFamily=&#8221;{Binding ElementName=FontList,Path=SelectedItem}&#8221;), and finally we&#8217;re binding the <strong>FontSize<\/strong> to the Value of the IntegerUpDown\u00a0control named FontSize.<\/p>\n<h2>Wrap up<\/h2>\n<p>If you run your application now you&#8217;ll see it works as expected and just like that you&#8217;ve made your very own\u00a0version of the FontViewer application, you&#8217;ve seen how to install additional components from within Visual Studio using NuGet package manager, and you&#8217;ve seen how to set the data binding between elements.<\/p>\n<p>Hope this proved to be helpful and got you excited about WPF in that manner that you&#8217;ll now go and do further exploring on your own.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TL;DR You can download from Github the demo application (zipped exe) or the whole source code project (Visual Studio project solution), or continue reading to see how it&hellip;<\/p>\n","protected":false},"author":1,"featured_media":548,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,33],"tags":[],"class_list":["post-492","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codeproject","category-wpf"],"_links":{"self":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/comments?post=492"}],"version-history":[{"count":10,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/492\/revisions"}],"predecessor-version":[{"id":2036,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/posts\/492\/revisions\/2036"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media\/548"}],"wp:attachment":[{"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/media?parent=492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/categories?post=492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nikola-breznjak.com\/blog\/wp-json\/wp\/v2\/tags?post=492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}