WinRT gridview添加磁贴

时间:2012-11-04 23:13:25

标签: c# windows gridview windows-runtime

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

我怎样才能拥有与GridView中每个其他网格项具有完全不同行为的静态图块?就像下图中的最后一个图块一样。

enter image description here

2 个答案:

答案 0 :(得分: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;
        }
    }
}

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

<selectors:LoadMoreTemplateSelector x:Key="LoadMoreTemplateSelector" 
       DefaultTemplate="{StaticResource Template1}" 
       LoadMoreTemplate="{StaticResource LoadMoreTemplate}"/>

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

<GridView ...
    ItemTemplateSelector="{StaticResource LoadMoreTemplateSelector}" />

LoadMoreTemplate看起来像这样:

<DataTemplate x:Key="LoadMoreTemplate">
   <Button Command="{Binding LoadMore}" Content="+"/>
</DataTemplate>

唯一剩下的问题是您必须在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);
        }
    }
}

当您实例化LoadMoreViewModel时,您可以提供在用户单击“加载更多”按钮时要执行的操作。

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

在页面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());
}

答案 1 :(得分:1)

您可以简单地编辑GridView的控件模板:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="GridView">
            <Border BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Background="{TemplateBinding Background}">
                <ScrollViewer x:Name="ScrollViewer">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="50" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <!-- Your custom buttons -->
                        <StackPanel Orientation="Vertical"
                                    Grid.Column="0">

                        </StackPanel>

                        <ItemsPresenter Grid.Column="1"
                                        HeaderTemplate="{TemplateBinding HeaderTemplate}"
                                        Header="{TemplateBinding Header}"
                                        HeaderTransitions="{TemplateBinding HeaderTransitions}"
                                        Padding="{TemplateBinding Padding}" />
                    </Grid>
                </ScrollViewer>
            </Border>
        </ControlTemplate>
    </Setter.Value>
</Setter>