2

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

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

在此处输入图像描述

4

2 回答 2

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;
        }
    }
}

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

<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());
}
于 2012-11-04T23:57:29.383 回答
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>
于 2012-11-27T16:22:45.450 回答