Archive for category WPF

Using the Strikethrough font on a WPF TextBlock

I had a list of tasks displayed in a StackPanel. Each row of tasks had a CheckBox and a TextBlock, the latter being the name of the task. When the user clicked the CheckBox, I wanted the task name to have a strikethrough font to signify that the task was done.

First, my XAML:

        <ItemsControl Canvas.Top="150" ItemsSource="{Binding}" Name="TaskList">
             <ItemsControl.ItemTemplate>
                 <DataTemplate>
                     <StackPanel Orientation="Horizontal">
                         <CheckBox Name="chkFinished" Checked="chkFinished_Clicked" IsChecked="{Binding Finished}" />
                         <TextBlock x:Name="lblTaskName" Text="{Binding TaskName}" />
                     </StackPanel>
                 </DataTemplate>
             </ItemsControl.ItemTemplate>
         </ItemsControl>

For semi-completeness, the data source that the ItemsControl is bound to is an ObservableCollection of a custom class called TaskList:

    public class TaskList
     {         
        public bool Finished { get; set; }
         public string TaskName { get; set; }
         public bool Recurring { get; set; }
        public TaskList(string taskName, bool recurring)
         {
             Finished = false;
             TaskName = taskName;
             Recurring = recurring;
         }
     }

The following few lines are in the Loaded event for the XAML Window control:

private void Window_Loaded(object sender, RoutedEventArgs e) {
 // Declaration. Code to pull records from the DB are not shown.
 ObservableCollection<TaskList> myList = new ObservableCollection<TaskList>() { };
// Bind the list 
ItemList.ItemsSource = myList; }

When the user clicks the Finished CheckBox, the  chkFinished_Clicked fires. The method looks for a matching record among the records bound, and when it finds one, it adds a TextDecoration item to the collection of TextDecorations associated with the TextBlock:

        protected void chkFinished_Clicked(object sender, EventArgs e)
         {
             StackPanel panel = (StackPanel)((CheckBox)sender).Parent;
                         // If any of the CheckBoxes are checked, change the font to strikethrough
             for (int i = 0; i < panel.Children.Count; i++)
             {
                 if (panel.Children[i].GetType().ToString() == "System.Windows.Controls.TextBlock")
                 {
                     ((TextBlock)panel.Children[i]).TextDecorations.Add(TextDecorations.Strikethrough);
                 }
             }
         }

Leave a comment

Getting the value of a WPF ComboBox

In case you were wondering how to set and get the value of a ComboBox in WPF, use the Tag property. So in this case, the Content is what’s visible to the user, and the Tag represents the behind the scenes value:

                <ComboBox Name="DataBase" Grid.Column="0" Grid.Row="1" SelectionChanged="DataBase_SelectionChanged">
                    <ComboBoxItem Content="One" Tag="1"/>
                    <ComboBoxItem Content="Two" Tag="2" />
                </ComboBox>

And to get value of the Tag property:

        private void DataBase_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBoxItem Item = (ComboBoxItem)DataBase.SelectedItem;
            MessageBox.Show("Value = " + Item.Tag);
        }

Leave a comment

Creating a Silverlight – WPF Button in code behind

In WPF or Silverlight, to add a Button from code behind insted of in XAML, first make sure the content control has a Children property. For example, I could not add to the SearchPanel Border control in the code below because it lacks such a property.

<Border Name="SearchPanel" CornerRadius="10" BorderBrush="Black" BorderThickness="1">
     <StackPanel Name="SearchStackPanel" />
</Border>

Why’s that? Border inherits from System.Windows.FrameworkElement, which lacks, you guessed it, the Children property. However, StackPanel inherits from System.Windows.Controls.Panel, which does have it.

Now, to actually add the button:

Button RandomButton = new Button();
RandomButton.Name = "RandomButton";
RandomButton.Content = "Random Location";
RandomButton.Click += new RoutedEventHandler(RandomButton_Click);
RandomButton.Height = 25.0;
RandomButton.Width = 100.0;
SearchStackPanel.Children.Add(RandomButton);
private void Random_Click(object sender, RoutedEventArgs e)
{
     // Stuff
}

Leave a comment

Changing the installation path in a Setup and Deployment project

I had created a Setup and Deployment project for a WPF application I had created. I noticed that when I installed the project, the path was being installed in the directory c:\Program Files\Awesome Place\FileTracker. As awesome as “Awesome Place” is, I didn’t want my application installed there – I wanted it installed at c:\Program Files\FileTracker.

What would Dr. Smith of Lost in Space fame do? He would say “the pain, the pain”, and then try to sabotage the Robinson family. That wasn’t going to help me, though, so I did some Google searching. And behold, I found the answer on Daniweb.

Here are the steps needed:

  1. Right click on the deployment project in the Solution window and select View, File System.
  2. Click on the Application Folder. Notice in the Properties window, the list of properties is refreshed, and one of the properties is DefaultLocation.
  3. Change the format to [ProgramFilesFolder]\[ProductName], removing the [Manufacturer] property from the mix.

(Click on the image to see a larger view.)

Change installation path of a Setup and Deployment project

Change installation path of a Setup and Deployment project

After you rebuild the deployment project, you can verify that the change has been made by right clicking on the deployment project and selecting Install. Stepping through the installation process, you’ll see that the target location is now the one that you want.

3 Comments

Notifying users when a long running process is ready

I was forced to delve into the world of Win32 coding to solve an issue of calling the SaveFileDialog method. I have a long-running WPF application that I wanted to get the user’s attention when it was finally ready for some love (i.e. the Save File dialog box appeared). I was having an issue where the app would quietly sit there until the user decided to check it – not the kind of passive relationship I was looking for. I needed to spice it up.

Luckily, I found the solution to shy application.

First, add a few DllImport statements to delve into the user32.dll file:

    <Runtime.InteropServices.DllImport("user32.dll")> _
    Private Shared Function ShowWindow(ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
    End Function
    <Runtime.InteropServices.DllImport("user32.dll")> _
    Private Shared Function SetForegroundWindow(ByVal hwnd As Integer) As Integer
    End Function
    <Runtime.InteropServices.DllImport("user32.dll")> _
    Private Shared Function IsIconic(ByVal hWnd As Integer) As Integer
    End Function

The meat of the code is this For Each loop. The only modification you will have to make is to change the MainWindowTitle to match the result of the window you want to give focus to:

        'Give focus to the dialog box when it is ready
        For Each p As Process In Process.GetProcesses
            If p.MainWindowTitle = "Results" Then
                If IsIconic(p.MainWindowHandle.ToInt32) <> 0 Then
                    ShowWindow(p.MainWindowHandle.ToInt32, &H1)
                Else
                    SetForegroundWindow(p.MainWindowHandle.ToInt32)
                End If
            End If
        Next

If you are interested in the internals of the calls, you can check MSDN for the IsIconic, ShowWindow and SetForegroundWindow functions.

Leave a comment

XAML error – System.Windows.Baml2006.TypeConverterMarkupExtension

Notice, if you will, this itty bitty block of code:

<ListBox Name="FilesList" ItemsSource="{Binding FileList}" Width="100%">
 <ListBox.ItemTemplate>
  <DataTemplate>
   <TextBlock Text="{Binding}" />
  </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>

While attempting to databind a custom collection class to a ListBox, I encountered an oddly named exception:

XamlParseException occurred
Provide value on 'System.Windows.Baml2006.TypeConverterMarkupExtension' threw an exception.

What the heck is Baml2006?

Anyway, here is the offending line:

<ListBox Name="FilesList" ItemsSource="{Binding FileList}" Width="100%">

Guess which part is the problem? The ‘Width=”100%”‘ part. When I changed it to read ‘Width=”350″‘, the error went away. No worries, but a more helpful error message would have been nice.

I’ve also received the “BAML” error where there are other invalid characters in a property value. So don’t put those invalid characters in property fields, kids – that’s bad.

1 Comment

Creating a flashing taskbar icon using FlashWindow with XAML

Looking to notify your users when an application wants its needs met? A sure fire way is to have its taskbar icon flash. Here’s how.

First, import those namespaces, people:

using System.Windows.Interop;
 using System.Runtime.InteropServices;

Next, declare the Windows API FlashWindow method.

[DllImport("user32")] public static extern int FlashWindow(IntPtr hwnd, bool bInvert);

Notice the first parameter is a IntPtr, NOT an int, like I found at one of the websites I visited trying to get this working. An int will get you nowhere. IntPtr is your friend.

Now create a WindowInteropHelper by passing the WPF Window object that you are calling the code from. Pass the window’s Handle property to the FlashWindow method, along with a value of “true”, to tell it that you want the awesome flashing taskbar effect.

WindowInteropHelper wih = new WindowInteropHelper(ThisWindow); 
FlashWindow(wih.Handle, true);

There we go, a simple way to alert users when your application is done or has updated information.

Leave a comment