Intersoft ClientUI Documentation
How-to: Customize UXFileUpload to an Outlook-style Attachment Uploader

This example shows how to customize the style and template of the UXFileUpload to achieve an elegant Outlook-style attachment upload control.

Example

Description

UXFileUpload uses MVVM design pattern approach in building the user interface and data communication through the means of binding. Consequently, UXFileUpload does not have strong reference to the UI elements and does not actually know the existence of the UI elements. As the results, you can change the user interface completely, for instances, changing the add button with a hyperlink, changing the progress bar with a busy indicator, adding new elements in certain visual state, or even completely redefine the entire user interface to your liking.

In this example, you will learn how to customize the visual state and style of the UXFileUpload control to achieve an Outlook-style attachment bar which displays the items in an inline wrapping panel.

Code

XAML
Copy Code
<Intersoft:UXPage 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:Intersoft="http://intersoft.clientui.com/schemas"
        xmlns:System="clr-namespace:System;assembly=mscorlib">

    <Intersoft:UXPage.Resources>
        <LinearGradientBrush x:Key="ItemBackground" EndPoint="0.5,1" StartPoint="0.5,0" Opacity="0.75">
            <GradientStop Color="White" Offset="0"/>
            <GradientStop Color="#FFE7EBF0" Offset="1"/>
        </LinearGradientBrush>

        <Intersoft:WarningVisibilityConverter x:Key="WarningVisibilityConverter"/>
        <Intersoft:SuccessVisibilityConverter x:Key="SuccessVisibilityConverter"/>
        <Intersoft:UXFileUploadResource x:Key="UploadResource"/>
        <Intersoft:ProgressBarVisibilityConverter x:Key="ProgressBarVisibilityConverter"/>

        <DataTemplate x:Key="UXFileUploadItemTemplate">
            <Grid>

                <Intersoft:UXProgressBar Value="{Binding ProgressPercentage}" Maximum="100"
                                         BorderThickness="0" CornerRadius="10" Opacity="0.8" Background="#FFE7E7E7"
                                         Visibility="{Binding State, Converter={StaticResource ProgressBarVisibilityConverter}}"/>

                <Intersoft:StylishLabel CornerRadius="10" Padding="8,2" BorderBrush="{x:Null}" Background="{x:Null}" MinWidth="80" MaxWidth="150">
                    <Intersoft:StylishLabel.Content>
                        <Intersoft:DockPanel FillChildMode="Custom">
                            <Intersoft:EllipsisText Intersoft:DockPanel.IsFillElement="True" 
                                                    Text="{Binding FileName}"/>

                            <StackPanel Orientation="Horizontal" Intersoft:DockPanel.Dock="Right">
                                <Image Source="/Assets/Images/success.png" Stretch="None"
                                           Visibility="{Binding State, Converter={StaticResource SuccessVisibilityConverter}}"/>
                                <Image Source="/Assets/Images/failed.png" Stretch="None"
                                           Visibility="{Binding State, Converter={StaticResource WarningVisibilityConverter}}"
                                           ToolTipService.ToolTip="{Binding Message}"/>
                            </StackPanel>

                            <Intersoft:UXFlatButton Intersoft:DockPanel.Dock="Right" Padding="0" DisplayMode="Image"
                                                    Command="Intersoft:UploadCommands.RemoveFile" CommandCannotExecute="Collapsed"
                                                    Icon="/Intersoft.ClientUI.Samples.UXInput;component/Assets/Images/remove_small.png"/>
                        </Intersoft:DockPanel>
                    </Intersoft:StylishLabel.Content>
                </Intersoft:StylishLabel>
            </Grid>
        </DataTemplate>

        <Style x:Key="AttachmentItemStyle" TargetType="Intersoft:UXFileUploadItem">
            <Setter Property="Margin" Value="4,2"/>
            <Setter Property="CornerRadius" Value="10"/>
            <Setter Property="BorderBrush" Value="#FFA1AFC0"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="{StaticResource ItemBackground}"/>
            <Setter Property="SeparatorVisibility" Value="Collapsed"/>
            <Setter Property="Height" Value="22"/>
        </Style>
                
        <Style x:Key="AttachmentUploadStyle" TargetType="Intersoft:UXFileUpload">
            <Setter Property="Background" Value="White"/>
                  <Setter Property="BorderThickness" Value="1"/>
                  <Setter Property="BorderBrush" Value="#FF8B8B8B"/>
                  <Setter Property="ItemTemplate" Value="{StaticResource UXFileUploadItemTemplate}"/>
                  <Setter Property="Intersoft:LocalizationManager.Resource" Value="{StaticResource UploadResource}"/>
                  <Setter Property="ItemContainerStyle" Value="{StaticResource AttachmentItemStyle}"/>
                  <Setter Property="Template">
                      <Setter.Value>
                           <ControlTemplate TargetType="Intersoft:UXFileUpload">
                               <Grid>
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="ItemsState">
                                            <VisualState x:Name="NoItems">
                                                <Storyboard>
                                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="EmptyStatusText" Storyboard.TargetProperty="Visibility">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <Visibility>Visible</Visibility>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                            <VisualState x:Name="HasItems"/>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="UploadStates">
                                            <VisualState x:Name="SelectFiles"/>
                                            <VisualState x:Name="Uploading"/>
                                            <VisualState x:Name="UploadCompleted"/>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="ErrorStates">
                                            <VisualState x:Name="NoErrors"/>
                                            <VisualState x:Name="HasErrors">
                                                <Storyboard RepeatBehavior="1x">
                                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ErrorImage">
                                                        <DiscreteObjectKeyFrame KeyTime="0">
                                                            <DiscreteObjectKeyFrame.Value>
                                                                <Visibility>Visible</Visibility>
                                                            </DiscreteObjectKeyFrame.Value>
                                                        </DiscreteObjectKeyFrame>
                                                    </ObjectAnimationUsingKeyFrames>
                                                    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ErrorImage">
                                                        <SplineDoubleKeyFrame KeyTime="0" Value="1"/>
                                                        <SplineDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
                                                        <SplineDoubleKeyFrame KeyTime="0:0:0.8" Value="1"/>
                                                    </DoubleAnimationUsingKeyFrames>
                                                </Storyboard>
                                            </VisualState>
                                        </VisualStateGroup>
                                        <VisualStateGroup x:Name="DragDropStates"/>
                                    </VisualStateManager.VisualStateGroups>

                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                                                        
                            <Border x:Name="AttachmentUploadElement" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                  <Grid>
                                        <TextBlock Name="EmptyStatusText" Foreground="Gray" Text="{Binding EmptyFilesStatus, Source={StaticResource UploadResource}}" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed"/>
                                        <Intersoft:UXScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" Margin="2">
                                            <Grid>
                                                <Image x:Name="ErrorImage" VerticalAlignment="Top" HorizontalAlignment="Right" Margin="4" Source="/Intersoft.Client.UI.Aqua.UXInput;component/Resources/attention.png" Stretch="None" ToolTipService.ToolTip="{TemplateBinding ErrorMessage}" Visibility="Collapsed"/>
                                                <ItemsPresenter/>
                                            </Grid>
                                          </Intersoft:UXScrollViewer>
                                    </Grid>
                            </Border>

                            <Intersoft:UXFlatButton Grid.Column="1" Command="Intersoft:UploadCommands.AddFiles" CommandCannotExecute="Collapsed" 
                                                    HorizontalAlignment="Right" VerticalAlignment="Top" DisplayMode="Image" 
                                                    Icon="/Assets/Images/addfile.png" 
                                                    Padding="0,2" ToolTipService.ToolTip="{Binding AddFilesTooltip, Source={StaticResource UploadResource}}" 
                                                    ImageHeight="12" ImageWidth="12" Margin="4,0,0,0"/>

                            <Border x:Name="DefaultElement" Visibility="Collapsed">
                                  <Intersoft:DockPanel FillChildMode="Custom">
                                    <Intersoft:UXToolBar x:Name="ToolBarElement"/>
                                      <Intersoft:UXStatusBar x:Name="StatusBarElement"/>
                                    </Intersoft:DockPanel>
                                </Border>
                            
                                <Border x:Name="DropPanel" Visibility="Collapsed"/>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>

                  <Setter Property="ItemsPanel">
                     <Setter.Value>
                          <ItemsPanelTemplate>
                              <Intersoft:WrapPanel/>
                          </ItemsPanelTemplate>
                     </Setter.Value>
                </Setter>
        </Style>

    </Intersoft:UXPage.Resources>

    <Grid x:Name="LayoutRoot">

      <Intersoft:UXFileUpload ServiceUrl="http://localhost:7373/UXFileUploadHandler.ashx"
                              TargetFolder="~/ClientBin/Assets"
                              TargetWebUrl="http://{host}/ClientBin/Assets"
                              Style="{StaticResource AttachmentUploadStyle}"/>

    </Grid>
</Intersoft:UXPage>

When used in an application, the UXFileUpload looks like the following illustration.

See Also

Concepts