WinRT gridview添加磁贴

May*_*ank 2 c# windows gridview windows-runtime

我有一个GridView和它绑定List的项目.我希望它有一个静态项目,以便用户可以点击它来添加更多项目.如果我点击其他项目,我会生成项目详细信息页面.

如何让静态磁贴与其他网格项具有完全不同的行为GridView?就像下图中的最后一个图块一样.

在此输入图像描述

Eil*_*aee 11

在我们的项目中,我们找到了一个干净的解决方案:GridView ItemsSource绑定到ViewModel的集合.最后一个可以是众所周知的VM,例如LoadMoreViewModel实例.

它允许您创建DataTemplateSelector实现并将其设置为GridView的ItemTemplateSelector属性.

public class LoadMoreTemplateSelector: DataTemplateSelector
{
    public DataTemplate LoadMoreTemplate { get; set; }
    public DataTemplate DefaultTemplate { get; set; }


    protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
    {
        if (item is LoadMoreViewModel)
        {
            return LoadMoreTemplate;
        }
        else
        {
           return DefaultTemplate;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

创建此TemplateSelector的实例作为xaml文件中的资源,并设置适当的模板:

<selectors:LoadMoreTemplateSelector x:Key="LoadMoreTemplateSelector" 
       DefaultTemplate="{StaticResource Template1}" 
       LoadMoreTemplate="{StaticResource LoadMoreTemplate}"/>
Run Code Online (Sandbox Code Playgroud)

您的gridView可以使用此模板选择器

<GridView ...
    ItemTemplateSelector="{StaticResource LoadMoreTemplateSelector}" />
Run Code Online (Sandbox Code Playgroud)

LoadMoreTemplate看起来像这样:

<DataTemplate x:Key="LoadMoreTemplate">
   <Button Command="{Binding LoadMore}" Content="+"/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

唯一剩下的问题是您必须在LoadMoreViewModel中实现ICommand以将加载更多按钮绑定到模板中,或者创建UserControl以便能够对Click事件做出反应.

编辑:这是一个简单的ICommand实现.单击按钮时,它将执行传递给构造函数的操作.

public class DelegateCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public event EventHandler CanExecuteChanged;

    public DelegateCommand(Action<object> execute) 
                   : this(execute, null)
    {
    }

    public DelegateCommand(Action<object> execute, 
                   Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public override bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public override void Execute(object parameter)
    {
        _execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        if( CanExecuteChanged != null )
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

实例化LoadMoreViewModel时,可以提供在用户单击"加载更多"按钮时要执行的操作.

public class LoadMoreViewModel:BindableBase
{
   public ICommand LoadMore{get;private set;}
   public LoadMoreViewModel(Action<object> action)
   {
     LoadMore = new DelegateCommand(action);
   }
}
Run Code Online (Sandbox Code Playgroud)

在页面ViewModel中,当在列表中加载更多项目时,删除列表末尾的当前LoadMoreViewModel,然后添加其他项目,最后再次添加LoadMoreViewModel(如果需要):

public void LoadMoreItems()
{
  if(Items.Last() is LoadMoreViewModel)
  {
    Items.Remove(Items.Last());
  }
  //Insert here add new items logic.
  Items.Add(new LoadMoreViewModel(_=>LoadMoreItems());
}
Run Code Online (Sandbox Code Playgroud)