sobota, 27 lutego 2016

Outlook - like UWP ListView

 GIF


XAML
<Page.Resources>
    <Style TargetType="ListViewItem" x:Key="ItemStyle">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Margin" Value="0"/>
        <Setter Property="MinHeight" Value="40"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <!--ListViewItemPresenter/-->
                    <ContentPresenter/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <DataTemplate x:Key="NarrowTemplate">
        <Grid>
            <Grid Grid.Column="0" 
                  Background="Red">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="40"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="" 
                           Grid.Column="0"
                           Margin="10,0,10,0" 
                           Foreground="White" 
                           VerticalAlignment="Center" 
                           FontFamily="Segoe MDL2 Assets"/>
                <TextBlock Text="Remove" 
                           Grid.Column="1"
                           Foreground="White"
                           VerticalAlignment="Center"
                           HorizontalAlignment="Left"/>
            </Grid>
            <Grid Grid.Column="0" 
                  Background="Green">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="100"/>
                    <ColumnDefinition Width="40"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="" 
                           Grid.Column="2" 
                           Margin="10,0,10,0" 
                           Foreground="White" 
                           VerticalAlignment="Center" 
                           FontFamily="Segoe MDL2 Assets"/>
                <TextBlock Text="Add" 
                           Grid.Column="1"
                           Foreground="White"
                           VerticalAlignment="Center"
                           HorizontalAlignment="Right"/>
            </Grid>
            <Grid ManipulationMode="TranslateX" 
                  ManipulationDelta="OnManipulationDelta"
                  ManipulationStarted="OnManipulationStarted"
                  ManipulationCompleted="OnManipulationCompleted" 
                  BorderBrush="Black"
                  BorderThickness="1" 
                  Background="#4383AF">
                <TextBlock Text="{Binding Path=LastName}" 
                           Padding="0" 
                           Margin="10,0,0,0" 
                           Foreground="White"
                           VerticalAlignment="Center"/>
           </Grid>
        </Grid>
    </DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" VerticalAlignment="Center"> 
    <StackPanel>
        <TextBlock Text="{Binding PeopleCollection.Count, Mode=TwoWay}" Width="200"/>
        <ListView IsItemClickEnabled="False" 
                  IsSwipeEnabled="False"
                  SelectionMode="None"
                  ItemTemplate="{StaticResource NarrowTemplate}"
                  ItemsSource="{Binding PeopleCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  ItemContainerStyle="{StaticResource ItemStyle}">
        </ListView>
    </StackPanel>
</Grid> 
Code behind
private double _currentPosition;
private void OnManipulationStarted(object sender, ManipulationStartedRoutedEventArgs e)
{
    //Reset top bar position 
    _currentPosition = 0;
}

private async void OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
    var grid = sender as Grid;

    if (_currentPosition > 100)
    {
        //Get name value from TextBlock
        var lastName = (grid.Children[0] as TextBlock).Text;

        //Get MVVM data context
        PeoplePageViewModel dc = DataContext as PeoplePageViewModel;
        var peopleList = dc.PeopleCollection;

        //Select single by name
        var selectedElement = dc.PeopleCollection.Single(x => x.LastName == lastName);
        //Remove it from list and trigger NotifyCollectionChanged 
        peopleList.Remove(selectedElement);
    }
    else
    {
        //If bar position is less than 100 reset it's position to initial state
        var el = sender as FrameworkElement;
        var transform = el.RenderTransform as CompositeTransform;
        if (transform == null)
            el.RenderTransform = transform = new CompositeTransform();
        transform.TranslateX = 0;

        //If bar postion is less than -100 additionally do some stuff
        if(_currentPosition < -100)
        {
            //Get name value from TextBlock
            var lastName = (grid.Children[0] as TextBlock).Text;
            AddFriend(lastName); 
            await new MessageDialog("Dodano do znajomych", lastName).ShowAsync();
        }
    }
}

private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var innnerGrid = sender as Grid;
    var el = sender as FrameworkElement;
    var transform = el.RenderTransform as CompositeTransform;
    if (transform == null)
        el.RenderTransform = transform = new CompositeTransform();

    var transformationResult = _currentPosition + e.Delta.Translation.X;
    var outerGrid = innnerGrid.Parent as Grid;  
 
    if (transformationResult < 0)
    {
        //Hide red bar and show green one 
        outerGrid.Children[1].Visibility = Visibility.Visible;
        outerGrid.Children[0].Visibility = Visibility.Collapsed;
    }
    else
    {
        //Hide green bar and show red on
        outerGrid.Children[0].Visibility = Visibility.Visible;
        outerGrid.Children[1].Visibility = Visibility.Collapsed;
    }

    transform.TranslateX += e.Delta.Translation.X;
    _currentPosition += e.Delta.Translation.X;
}

1 komentarz:

  1. what if we need both swipe actions are on the left side ???

    OdpowiedzUsuń