Click here to Skip to main content
15,884,472 members
Articles / Desktop Programming / WPF

WPF Attachment Control

Rate me:
Please Sign up or sign in to vote.
4.00/5 (3 votes)
15 Dec 2009CPOL2 min read 27.9K   680   6   1
Attachment control using WPF.

Image 1

Introduction

This control is a ListView control that holds a list of attachments, which has a link to the attachments and some metadata about them. This article demonstrates the basics of WPF controls and templating, including binding a list control to application data. The project includes the AttachmentList control which is a templated ListView, and a demo window which holds the application data and binds the data to the control.

Using the code

The control is made from a list box which holds the Attachment class that is defined by AttachmentTemplate that is set to the ListView ItemTemplate property.

XML
<ListBox IsSynchronizedWithCurrentItem="True" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch" 
         x:Name="AttachmentListBox" 
         HorizontalContentAlignment="Stretch"
         SelectionChanged="AttachmentListBox_SelectionChanged"
         ItemTemplate="{DynamicResource AttachmentTemplate}"
         Margin="0,32,0,0"
         >

The control template is built from five rows, the attachment icon:

XML
<Image x:Name="AttachmentIcon" 
    Source="\Images\attach.png" HorizontalAlignment="Left" />

and a text block for the title of the attachment:

XML
<TextBlock x:Name="Title"
          Margin="16,0,0,0"
          Text="Title" HorizontalAlignment="Left"/>

The next block is the main data for the attachment which is separated into two columns: A text block which is multi-bound to UpdateUser and UpdateUserTime.

XML
<TextBlock x:Name="CreationText" 
         Margin="0,0,0,0" 
         Grid.Column="0" 
         HorizontalAlignment="Left">
   <TextBlock.Text>
        <MultiBinding StringFormat="Edited by {0} on {1}">
           <Binding Path="UpdateUser"/>
           <Binding Path="UpdateDateTime"/>
        </MultiBinding>
   </TextBlock.Text>
</TextBlock>

And another text block which is multi-bound to UpdateUser and UpdateUserTime.

XML
<TextBlock x:Name="UpdatingText" 
        Margin="2,0,0,0" Grid.Column="1" 
        HorizontalAlignment="Right">
  <TextBlock.Text>
    <MultiBinding StringFormat="Created by {0} on {1}">
      <Binding Path="CreationUser"/>
      <Binding Path="CreationDateTime"/>
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

The next row defines the file icon and the hyperlink to that file:

XML
<Grid Grid.Row="2" >
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="*"/>
  </Grid.ColumnDefinitions>
  <Image x:Name="FileIcon" Source="/Images/File.png"
  Grid.Column="0" HorizontalAlignment="Left"/>
  <TextBlock x:Name="FilePath" Margin="2,0,0,0" Grid.Column="1">
    <Hyperlink NavigateUri="{Binding Path=FilePath}" 
              Hyperlink.RequestNavigate="Hyperlink_RequestNavigate">
      <TextBlock Text="{Binding Path=FileName}"/>
    </Hyperlink>
  </TextBlock>
</Grid>

A thing to mention here is the Hyperlink.RequestNavigate event, which is called upon pressing the hyperlink. You have to implement this event if you want the hyperlink to operate as you need it; otherwise, it does nothing. In our case, I implemented it by using System.Diagnostics.Process.Start in the code-behind, as follows:

C#
System.Diagnostics.Process.Start(e.Uri.ToString());

Simple, once you know this. The last text block is for the description of the attachment, which is a simple text block. Next, we have the control toolbar which defines two actions: add attachment and delete attachment.

XML
<ToolBar Height="32" x:Name="AttachmentsToolbar" VerticalAlignment="Top">
  <Button x:Name="AddAttachment" Command="{Binding Controller.AddAttachmentCommand}">
    <Image Source = "/Images/attach.png"/>
  </Button>
  <Button x:Name="DeleteAttachment" 
            Command="{Binding Controller.DeleteAttachmentCommand}">
    <Image Source = "/Images/delete32.png"/>
  </Button>
</ToolBar>

Notice that the command for the actions is binding, which is done by using a DelegateCommand which is defined in Prism. The delegate command is attached in the project so you don't need to worry about this part. A DelegateCommand is an easy way of implementing Commands in your application. For further information, follow this link: http://development-guides.silverbaylabs.org/Video/Prism-Commands.

And... I think that's about it. The code-behind is straightforward... so I didn't go in to much detail there. I am waiting for your comments...

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Israel Israel
Fields of interest: Software - .NET, C#, WPF, WCF, JAVA, software architecture and design.
Professional experience: 10 years of software management and development.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Destenkov16-Dec-09 1:57
Destenkov16-Dec-09 1:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.