티스토리 뷰

반응형

기본적으로 제공하는 템플릿 소스에 drag&drop으로 아이템을 이동하는 간단한 소스를 만들어 보았다.

앱 개발에 적용하기 위해서는 추가적인 작업이 필요하니 참고하기 바란다.

 

 

 

1. GroupedItemsPage.xaml

CanDragItems, AllowDrop, CanRecorderItems 프로퍼티를 변경한다.

VirtualizingStackPanel은 데이터의 표현 방법에 따라서 여러가지로 변경하면서 확인한다.

 

        <GridView
            x:Name="itemGridView"
            AutomationProperties.AutomationId="ItemGridView"
            AutomationProperties.Name="Grouped Items"
            Grid.RowSpan="2"
            Padding="116,137,40,46"
            ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
            ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
            SelectionMode="None"
            IsSwipeEnabled="false"
            IsItemClickEnabled="True"
            ItemClick="ItemView_ItemClick"
            CanDragItems="True"
            AllowDrop="True"
            CanReorderItems="True">

            <GridView.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </GridView.ItemsPanel>
            <GridView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.HeaderTemplate>
                        <DataTemplate>
                            <Grid Margin="1,0,0,6">
                                <Button
                                    AutomationProperties.Name="Group Title"
                                    Click="Header_Click"
                                    Style="{StaticResource TextPrimaryButtonStyle}" >
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock Text="{Binding Title}" Margin="3,-7,10,10" Style="{StaticResource GroupHeaderTextStyle}" />
                                        <TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" Style="{StaticResource GroupHeaderTextStyle}"/>
                                    </StackPanel>
                                </Button>
                            </Grid>
                        </DataTemplate>
                    </GroupStyle.HeaderTemplate>
                    <GroupStyle.Panel>
                        <ItemsPanelTemplate>
                            <VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,80,0"/>
                        </ItemsPanelTemplate>
                    </GroupStyle.Panel>
                </GroupStyle>
            </GridView.GroupStyle>
        </GridView>

 

2. GroupedItemsPage.xaml.cs

namespace ItemDragDropSample
{
    /// <summary>
    /// A page that displays a grouped collection of items.
    /// </summary>
    public sealed partial class GroupedItemsPage : ItemDragDropSample.Common.LayoutAwarePage
    {
        public GroupedItemsPage()
        {
            this.InitializeComponent();
        }

        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);
            this.DefaultViewModel["Groups"] = sampleDataGroups;

            itemGridView.DragItemsStarting += itemGridView_DragItemsStarting;
            itemGridView.DragOver += itemGridView_DragOver;
            itemGridView.Drop += itemGridView_Drop;

        }

 

        object dragOverItem = null;

 

        /// <summary>
        /// 드롭 처리
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void itemGridView_Drop(object sender, DragEventArgs e)
        {
            object gridSource;
            e.Data.Properties.TryGetValue("gridSource", out gridSource);
            if (gridSource != sender)
                return;

            object sourceItem;
            e.Data.Properties.TryGetValue("item", out sourceItem);
            if (sourceItem == null)
                return;

            if (dragOverItem == null) return;

            var groups = this.DefaultViewModel["Groups"] as ObservableCollection<SampleDataGroup>;
            var sourceGroupItem = (from kkk in groups
                                   from jjj in kkk.Items
                                   let sIndex = kkk.Items.IndexOf(jjj)
                                   where jjj.UniqueId == (sourceItem as SampleDataCommon).UniqueId
                                   select new { Sgroup = kkk, Sitem = jjj, SItemIndex = sIndex} ).FirstOrDefault();
            var targetGroupItem = (from kkk in groups
                                   from jjj in kkk.Items
                                   let tIndex = kkk.Items.IndexOf(jjj)
                                   where jjj.UniqueId == (dragOverItem as SampleDataCommon).UniqueId
                                   select new { Tgroup = kkk, Titem = jjj, TItemIndex = tIndex }).FirstOrDefault();
            if (sourceGroupItem.Sgroup.Equals(targetGroupItem.Tgroup))
            {
                sourceGroupItem.Sgroup.Items.Move(sourceGroupItem.SItemIndex, targetGroupItem.TItemIndex);
            }
            else
            {
                sourceGroupItem.Sgroup.Items.Remove(sourceGroupItem.Sitem);
                targetGroupItem.Tgroup.Items.Insert(targetGroupItem.TItemIndex, sourceGroupItem.Sitem);
            }
        }

 

        /// <summary>
        /// 아이뎀이 어떤 위치에있는지 확인
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void itemGridView_DragOver(object sender, DragEventArgs e)
        {
            FrameworkElement element = e.OriginalSource as FrameworkElement;
            var groups = this.DefaultViewModel["Groups"] as ObservableCollection<SampleDataGroup>;
            if (element != null )
            {
                var item = element.DataContext as SampleDataCommon;
                if(item != null)
                {
                    dragOverItem = groups.SelectMany(p => p.Items).FirstOrDefault(p => p.UniqueId == item.UniqueId);
                }
            }
        }

 

        /// <summary>
        /// 아이템 드래그 시작
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void itemGridView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
        {
            var item = e.Items.FirstOrDefault();
            if (item == null)
                return;

            e.Data.Properties.Add("item", item);
            e.Data.Properties.Add("gridSource", sender);
        }


        void Header_Click(object sender, RoutedEventArgs e)
        {
            var group = (sender as FrameworkElement).DataContext;

            this.Frame.Navigate(typeof(GroupDetailPage), ((SampleDataGroup)group).UniqueId);
        }

        void ItemView_ItemClick(object sender, ItemClickEventArgs e)
        {
            var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;
            this.Frame.Navigate(typeof(ItemDetailPage), itemId);
        }
    }
}

 

3. Source

 

ItemDragDropSample.zip

반응형
댓글