Wednesday, May 29, 2013

WPF Effects and Blurry Fonts

I recently ran into a very strange bug that took me a while to figure out. I noticed that several buttons in my UI had blurry text. I thought I may have mistakenly changed the opacity or had some semi-transparent gradient overlaying the font that made it look so blurry. That did not turn out to be the case. After digging around a bit I found out what was causing the problem. It turns out that the problem was in my control template. I defined the button to have a border which contains a label inside it’s content. I applied the drop shadow to the outer border and was surprised to find that applying that effect to the border caused the contents of the border to become blurry. After a little research I found that using an effect causes the elements and all the sub-elements inside the control to be rendered into a Bitmap. When this happens, WPF cannot use ClearType rendering to display the text. This causes it to look blurrier than if there is not effect applied.

Here is what my buttons looked like with the drop shadow

image

And here is the same button without the drop shadow

image

To get around this bug simply place the text outside of the control that you will be applying the effect to.

<Border>
     <Border.Effect>
          …
     </Border.Effect>
     <TextBlock Text=”Blurry Text”/>
</Border>

//Change the code above to this.

<Grid>
     <Border>
          <Border.Effect>
                …
          </Border.Effect>
     </Border>

     <TextBlock Text=”Clear Text”/>
</Grid>

If you run into this issue, just change your code like what I did above and you should have clear text on your buttons even if you are using effects.

Happy Coding.

Tuesday, April 16, 2013

Using Animated Gifs with WPF

Ever wish you could use an animated gif in your WPF application? Well, here is an easy way to do so. Simply use the WpfAnimatedGif Nuget package available on codeplex. With that library, you can easily display animated GIFs in your application via XAML or code.

Here is what the markup looks like…

 xmlns:a=http://wpfanimatedgif.codeplex.com





<Image a:ImageBehavior.AnimatedSource="Images/myImage.gif"/>


Head over to http://wpfanimatedgif.codeplex.com/ for more info.



Happy Coding!



Monday, April 15, 2013

Iterate through Dictionary Entries in Merged Dictionaries

Just a quick post to show you how to iterate through resource dictionary entries when using merged resource dictionaries. It is fairly straight forward. I came across someone wondering how to do this, so I thought I’d share. You simply iterate through all your merged dictionaries and then iterate through each dictionary entry in the dictionary. Here is the code below.

foreach (ResourceDictionary dict in Application.Current.Resources.MergedDictionaries)
{
foreach (DictionaryEntry entry in dict)
{
//Process entry

}
}



Hope this helps.



Monday, April 1, 2013

MessageDialog - Windows Store App MessageBox.Show Equivalent.

If you are new to Windows Store app development, you may be wondering how to show a simple dialog. It used to be so easy. You simply called MessageBox.Show() and you had a dialog. Well, in Windows Store Applications in Windows 8, it is a bit different but just as easy.

Try this code instead of MessageBox.Show to get the following dialog…

var messageDialog = new Windows.UI.Popups.MessageDialog("Message Text.","Message Header");
messageDialog.ShowAsync();


image


Happy Windows Store App Coding!



Sunday, March 31, 2013

Windows Store App… How to set focus on a textbox

A common task in UI development is setting the focus on a textbox when navigating to a particular screen. When doing this on a Windows 8 application, a lot of developers try to do this inside the OnNavigatedTo event handler. This does not work. To set the focus on a textbox when the page is hit, call the focus method on the particular textbox inside the loaded event handler… That should do it.

<common:LayoutAwarePage
x:Name="pageRoot"

Loaded="pageRoot_Loaded_1">



private void pageRoot_Loaded_1(object sender, RoutedEventArgs e)
{
this.txtName.Focus(FocusState.Programmatic);
}



Hope this helps. Happy Coding!



Friday, March 29, 2013

ChangeAwareContentControl–How to know when the content changes in a ContentControl

I am working on an application where I have a ContentControl, and I need to know when the content changes. My initial thought was to add an event handler for the ContentChanged event. I came to find out that the ContentControl does not fire a ContentChanged event.

My solution was to create a control derived from content control that fires that particular event. It is working quite nicely, so I thought I would share. I hope it helps you out. It’s a small amount of code, but it does the trick.

    public class ChangeAwareContentControl : ContentControl
{
static ChangeAwareContentControl()
{
ContentProperty.OverrideMetadata(
typeof(ChangeAwareContentControl),
new FrameworkPropertyMetadata(
new PropertyChangedCallback(OnContentChanged)));
}

private static void OnContentChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
ChangeAwareContentControl mcc = d as ChangeAwareContentControl;
if (mcc.ContentChanged != null)
{
DependencyPropertyChangedEventArgs args
=
new DependencyPropertyChangedEventArgs(
ContentProperty, e.OldValue, e.NewValue);
mcc.ContentChanged(mcc, args);
}
}

public event DependencyPropertyChangedEventHandler ContentChanged;
}


Here is how you use it in xaml.



<controls:ChangeAwareContentControl ContentChanged="ContenChangedHandler"/>


Thursday, March 28, 2013

BitmapImage.BeginInit()

A very common error new UI developers make is trying to create new BitmapImages without properly initializing them.

All property changes made to a BitmapImage must be made between the BeginInit() and EndInit() calls. Every property change made after the EndInit() call is ignored.

Here is a small code snippet on how to properly create a new bitmap image and set that as the source of an Image object.

// Define a BitmapImage.
Image myImage = new Image();
BitmapImage bi = new BitmapImage();

// Begin initialization.
bi.BeginInit();

// Set BitmapImage properties. (CacheOption,CreateOptions… etc.)

// End initialization.
bi.EndInit();


myImage.Source = bi;