【问题标题】:How do I add an item after databinding?数据绑定后如何添加项目?
【发布时间】:2014-11-13 21:00:36
【问题描述】:

我正在尝试将一些数据绑定到 gridview,然后在末尾有一个按钮(类似于 Windows 8 上的 MSN Finance 应用程序)。

我将如何实现这一目标?

我当前的 xaml 代码:

            <DataTemplate>
                <GridView
                    x:Name="StopGridViewItem"
                    ItemsSource="{Binding}"
                    Margin="0,0,20,20"
                    AutomationProperties.AutomationId="ItemGridView"
                    AutomationProperties.Name="Items In Group"
                    ItemTemplate="{StaticResource Standard310x260ItemTemplate}"
                    SelectionMode="None"
                    IsSwipeEnabled="false"
                    IsItemClickEnabled="True" ItemClick="StopGridViewItem_ItemClick">
                </GridView>


            </DataTemplate>

提前致谢!

【问题讨论】:

    标签: c# windows xaml


    【解决方案1】:

    有很多很多方法可以处理这种情况。

    如果您正在处理一个简单的列表,而不是像我们在屏幕截图右侧看到的那样的动态马赛克,您可以简单地在列表后面放置一个按钮,使其看起来像你的清单。当您处理不自动滚动的列表并且是最符合语义的解决方案时,这非常有效。

    <DataTemplate>
        <StackPanel>
            <ItemsControl
                x:Name="StopGridViewItem"
                ItemsSource="{Binding}"
                ItemTemplate="{StaticResource Standard310x260ItemTemplate}">
            </ItemsControl>
    
            <Button ... />
        </StackPanel>
    </DataTemplate>
    

    如果您需要支持滚动,或者正在处理不能像马赛克一样简单地将按钮向下推的控件,则需要在绑定到列表的集合中添加一个虚拟项目。如果列表虚拟化不是问题,您可以简单地将其附加到转换器内的集合末尾。如果您需要支持虚拟化,那么这不是一个解决方案。您将需要一个自定义控件来处理这种情况。

    最后,一旦将虚拟项目插入列表中,您可以在视图中生成项目时使用 DataTemplateSelector 在普通模板和虚拟模板之间切换。

    public static class EnumerableExtensions
    {
        public static IEnumerable Append(this IEnumerable source, object o)
        {
            foreach (var x in source)
            {
                yield return x;
            }
    
            yield return o;
        }
    }
    
    public class DummyInserter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var source = value as IEnumerable;
            if (source == null)    throw new UnsupportedException("DummyInserter converter requires an IEnumerable source");
    
            return source.Append(new Dummy()).ToArray();
        }
    }
    

    对于 XAML:

    <Resources>
        <DummyInserter x:key="AddButtonDummyInserter" />
        <DummyTemplateSelector x:key="MySelector"
                               DefaultTemplate="{StaticResource Standard310x260ItemTemplate}"
                               DummyTemplate="{StaticResource 310x260AddButtonTemplate}" />
    </Resources>
    
    <DataTemplate>
        <StackPanel>
            <ItemsControl
                x:Name="StopGridViewItem"
                ItemsSource="{Binding, Converter={StaticResource AddButtonDummyInserter}}"
                ItemTemplateSelector="{StaticResource MySelector}">
            </ItemsControl>
    
            <Button ... />
        </StackPanel>
    </DataTemplate>
    

    【讨论】:

      【解决方案2】:

      将其添加到GridViewItemsSource 绑定到的任何ObservableCollection&lt;T&gt;


      如果 FooterGridRow 还不够。然后您可以使用ItemTemplateSelector 以更复杂的方式进行操作

      <Page.Resources>
          <DataTemplate x:Key="AddTemplate">
              <Button Command="{Binding}" Content="{Binding Title}" Height="100" MinHeight="100" Width="100" MinWidth="100"/>
          </DataTemplate>
          <DataTemplate x:Key="DefaultTemplate">
              <Border BorderThickness="1" BorderBrush="Red">
                  <StackPanel Height="100" MinHeight="100" Width="100" MinWidth="100">
                      <TextBlock Text="{Binding Artist}"></TextBlock>
                      <TextBlock Text="{Binding Song}"></TextBlock>
                  </StackPanel>
              </Border>
          </DataTemplate>
          <local:MyTemplateSelector x:Key="MyTemplateSelector" AddTemplate="{StaticResource AddTemplate}" DefaultTemplate="{StaticResource DefaultTemplate}"></local:MyTemplateSelector>
      </Page.Resources>
      
      <GridView x:Name="myGV" ItemTemplateSelector="{StaticResource MyTemplateSelector}"></GridView>        
      

      public class MyTemplateSelector : DataTemplateSelector
      {
          public DataTemplate AddTemplate { get; set; }
      
          public DataTemplate DefaultTemplate { get; set; }
      
      
          protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container)
          {
              if (item is sample_model)
              {
                  return DefaultTemplate;
              }
              else
              {
                  return AddTemplate;
              }
          }
      }
      

      基本上,您可以在GridView.Items 中添加任意数量的models,它所做的只是检查它是什么模型类型,如果是sample_model(您的模型),它将使用默认模板,但是如果它不是默认模型,那么它使用 AddTemplate(这是按钮之一)

      使用(艺术家/歌曲)的 sample_model 和仅具有 Title 属性的非默认模型的示例输出

      【讨论】:

      • 但是如果该项目与其他对象不同怎么办?例如。一个“+”按钮而不是标准数据集
      • @ForeverLearning "+" 按钮不是 ItemTemplate 的一部分,它是 &lt;GridView.FooterTemplate&gt;&lt;/GridView.FooterTemplate&gt; msdn.microsoft.com/en-us/library/… 的一部分(所以基本上它是您可以在列表末尾始终拥有的项目,与它自己的绑定/模板)
      • @ForeverLearning 如果您在顶部容器中包含上一行中的列表,您还可以将“+”添加为单独的行。
      • 感谢您的澄清,尝试了这个,但页脚模板在包含按钮的网格视图中创建了一个单独的列,而不是将其标记到项目列表的末尾?
      • @Chubosaurus Software 这不会将按钮保留在列表中。页脚是独立于列表绘制的,如果您的面板不是像堆栈面板这样简单的单向面板,这将导致问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 1970-01-01
      • 2023-03-08
      • 2012-10-27
      • 2010-11-12
      • 2012-09-04
      • 2012-03-19
      相关资源
      最近更新 更多