Intersoft ClientUI Documentation
How-to: Customize UXFileUpload to a Gmail-style Inline Uploader

This example shows how to customize the style and template of the UXFileUpload to achieve an inline, Gmail-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 a Gmail-style attachment bar which displays a very simple hyperlink to attach a file. The selected file will be automatically uploaded, while users are allowed to attach another file.

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>

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

        <DataTemplate x:Key="UXFileUploadItemTemplate">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <Intersoft:EllipsisText Text="{Binding FileName}" MaxWidth="120"/>
                    
                    <TextBlock Text="{Binding Size, Converter={StaticResource ByteConverter}}" Margin="8,0" VerticalAlignment="Center"/>

                    <Intersoft:UXProgressBar Value="{Binding ProgressPercentage}" Maximum="100" Width="150" Height="16"
                                             Visibility="{Binding State, Converter={StaticResource ProgressBarVisibilityConverter}}"/>

                    <Intersoft:UXFlatButton Margin="4" Command="Intersoft:UploadCommands.CancelFileUpload" CommandCannotExecute="Collapsed">
                        <Image Source="/Intersoft.Client.UI.Aqua.UXInput;component/Resources/remove.png" Height="12"/>
                    </Intersoft:UXFlatButton>

                    <Image Source="/Intersoft.ClientUI.Samples.UXInput;component/Assets/Images/success.png" Stretch="None"
                                Visibility="{Binding State, Converter={StaticResource SuccessVisibilityConverter}}"/>

                    <Image Source="/Intersoft.ClientUI.Samples.UXInput;component/Assets/Images/failed.png" Stretch="None"
                                Visibility="{Binding State, Converter={StaticResource WarningVisibilityConverter}}"
                                ToolTipService.ToolTip="{Binding Message}"/>

                </StackPanel >
            </Grid>
        </DataTemplate>

        <Style x:Key="AttachmentItemStyle" TargetType="Intersoft:UXFileUploadItem">
            <Setter Property="CornerRadius" Value="0"/>
            <Setter Property="BorderBrush" Value="{x:Null}"/>
            <Setter Property="Background" Value="{x:Null}"/>
            <Setter Property="SeparatorVisibility" Value="Collapsed"/>
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="Height" Value="25"/>
        </Style>

        <Style x:Key="GmailUploadStyle" TargetType="Intersoft:UXFileUpload">
            <Setter Property="Background" Value="{x:Null}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="BorderBrush" Value="{x:Null}"/>
            <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"/>
                                    <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>
                            
                            <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                                <Grid>
                                    <StackPanel>
                                        <ItemsPresenter/>
                                        <StackPanel Orientation="Horizontal">
                                            <Intersoft:UXHyperlinkButton Content="Attach a file" Intersoft:DockPanel.Dock="Right" Command="Intersoft:UploadCommands.AddFiles" Foreground="#FF0D64AB" FontSize="12" DisplayMode="ContentAndImage" Icon="/Intersoft.ClientUI.Samples.UXInput;component/Assets/Images/attachment.png"/>
                                            <Image x:Name="ErrorImage" Intersoft:DockPanel.Dock="Right" Margin="8,0" Source="/Intersoft.Client.UI.Aqua.UXInput;component/Resources/attention.png" Stretch="None" ToolTipService.ToolTip="{TemplateBinding ErrorMessage}" Visibility="Collapsed"/>
                                        </StackPanel>
                                    </StackPanel>
                                </Grid>
                            </Border>
                            <Border x:Name="DefaultElement" Visibility="Collapsed">
                                <Intersoft:DockPanel FillChildMode="Custom">
                                    <Intersoft:UXToolBar x:Name="ToolBarElement"/>
                                    <Intersoft:UXScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto"/>
                                    <Intersoft:UXStatusBar x:Name="StatusBarElement"/>
                                </Intersoft:DockPanel>
                            </Border>
                            <Border x:Name="DropPanel" Visibility="Collapsed"/>
                        </Grid>
                    </ControlTemplate>
                </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 GmailUploadStyle}"
                              IsAutomaticUpload="True" CanSelectMultiple="False" 
                              ShowStatisticsOnCompleted="False" />

    </Grid>
</Intersoft:UXPage>

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

See Also

Concepts