UWP在Xbox上重新排序Gridviewitems

时间:2018-02-05 22:36:45

标签: xaml gridview uwp xbox-one reorderlist

我正在制作一个UWP应用程序,该应用程序现在应该在xbox上,也许将来可能会在PC和其他平台上发布它。我知道在PC和移动设备上,我们可以通过GridViewListView上的以下2个属性启用此功能。

CanReorderItems=True
CanDrop=True

但根据Microsoft Docs,拖放功能为not available or supported on xbox

那么在xbox GridView上实现此重新排序功能的其他选项是什么?

更新1

  

所以这是gridview的后端代码。选择模式是单一的,但我没有使用selectionchanged事件,因为这只会产生很多混乱,现在只是假设我们总是需要交换项目,我将在交换完成后稍后设置布尔值。

private void SamplePickerGridView_ChoosingItemContainer(Windows.UI.Xaml.Controls.ListViewBase sender, ChoosingItemContainerEventArgs args)
    {
        if (args.ItemContainer != null)
        {
            return;
        }
        GridViewItem container = (GridViewItem)args.ItemContainer ?? new GridViewItem();
        //should be xbox actually after pc testing
        if (DeviceTypeHelper.GetDeviceFormFactorType() == DeviceFormFactorType.Desktop)
        {
            container.GotFocus += Container_GotFocus;
            container.LostFocus += Container_LostFocus;
            //container.KeyDown += Container_KeyDown;
        }
        args.ItemContainer = container;
    }
    private TVShow GotItem, LostItem;
    private void Container_LostFocus(object sender, RoutedEventArgs e)
    {

        LostItem = OnNowAllGridView.ItemFromContainer(e.OriginalSource as GridViewItem) as TVShow;
        GotItem = null;

    }

    private void Container_GotFocus(object sender, RoutedEventArgs e)
    {

        GotItem = OnNowAllGridView.ItemFromContainer(e.OriginalSource as GridViewItem) as TVShow;
        if (GotItem != null && LostItem != null)
        {
            var focusedItem = GotItem;
            var lostitem = LostItem;
            var index1 = ViewModel.Source.IndexOf(focusedItem);
            var index2 = ViewModel.Source.IndexOf(lostitem);
            ViewModel.Source.Move(index1, index2);
        }
        LostItem = null;

    }
  

你可以尝试使用adaptivegridview的代码,或者只是普通的uwp网格视图,如果它适用于它也应该与adaptivegridview一起工作。

当前Bheaviour 项目被转换但焦点保持在相同的索引。

预期焦点也应随项目一起移动。

1 个答案:

答案 0 :(得分:1)

你的发现是真的,开箱即用的Xbox不支持拖放(虽然将来鼠标支持Xbox,我想它会起作用。)

因此,如果您需要此功能,则必须从头开始手动实施。一个选项是添加一个按钮,该按钮仅显示在Xbox上,读起来像Reorder Grid

当这个"重新排序"模式已启用,您可以使用多种解决方案。

最简单的解决方案就是将SelectionMode设置为Single,当选择某个项目时,您可以将其从基础集合中删除。< / p>

collection.Remove( selectedItem );
collection.Insert( 0, selectedItem );

这个带来前面的解决方案是在Xbox One仪表板上实现的,用于重新排序磁贴。

第二个选项是将SelectionMode设置为Multiple,其中用户首先选择一个项目,然后选择第二个项目。之后,您可以在选择的第二个项目之前移动第一个选定的项目:

collection.Remove( firstSelectedItem );
var targetIndex = collection.IndexOf( secondSelectedItem );
collection.Insert( targetIndex, firstSelectedItem );

最后一个解决方案是最复杂的。使用SelectionMode = Single,您可以选择单个项目,然后观察用户焦点移动的方向并实时移动图块#34;。这是用户最友好的,但最难以可靠地实施。

正如第三个解决方案的大纲一样 - 如果您实施GotFocus的自定义模板,则可以捕获GridView事件:

<GridView.ItemsPanel>
    <ItemsPanelTemplate>
        <ItemsWrapGrid Orientation="Horizontal" 
                       GotFocus="GridViewItem_GotFocus"/>
    </ItemsPanelTemplate>
</GridView.ItemsPanel>

现在,在此GotFocus处理程序中,您可以从EventArgs.OriginalSource检索当前焦点的项目。通过这种方式,您可以知道哪个项目获得了焦点,您可以将其与用户选择的项目进行交换。

更新 - hacky解决方案

我提出了一种解决GotFocus / LostFocus混乱问题的hacky方法。

GotFocus的问题在于,当我们在集合中移动项目时,焦点会变得混乱。但如果我们没有完全移动物品会怎样?

假设您的商品类型为TVShow。让我们围绕这种类型创建一个包装器:

public class TVShowContainer : INotifyPropertyChanged
{
    private TVShow _tvShow;

    public TVShow TvShow
    {
        get => _tvShow;
        set
        {
            _tvShow = value; 
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

现在将集合项类型更改为这个新的&#34;包装器&#34;类型。当然,您还必须更新GridView DataTemplate以获得正确的参考。您现在需要使用"{Binding Property}",而不是"{Binding TvShow.Property}",或者您可以将DataContext="{Binding TvShow}"属性设置为DataTemplate内的根元素。

但是你现在可以看到我要去哪里了。目前,您正在使用Move方法移动集合中的项目。让我们用交换替换它:

var item1 = focusedItem.TvShow;
focusedItem.TvShow = LostItem.TvShow;
LostItem.TvShow = item1;

这是一个很大的区别,因为我们不再更改集合本身,而只是将引用移动到包含在&#34; static&#34;中的项目。容器。并且由于绑定,项目将正确地显示在他们应该的位置。

这仍然是一个hacky解决方案,因为它要求你只是为了重新排序包装你的项目,但它至少有效。然而,我仍然有兴趣找到更好的方法来做到这一点。