c# - 在 Windows App Store Gridview 中迭代选定的项目

标签 c# gridview winrt-xaml mvvm-light

我知道这很长,但请耐心等待。

我使用 MVVM light 框架在 MVVM light samples 中创建了一个与 Laurent Bugnion 的“MyFriends”程序非常相似的 Windows 应用程序商店程序。

在他的程序中,他使用 gridview 的 SelectedItem 属性来跟踪哪个项目是所选项目。

问题是,我让用户能够在 GridView 上选择多个项目,然后使用 App Bar 上的按钮对其进行操作。对于这个 SelectedItem 将不起作用。

有谁知道如何使用多选 GridView 进行这项工作?我已经根据 WPF 上的一些文章尝试了 GridViewItem 的 IsSelected 属性,但这似乎不起作用。 SelectedTimesheets getter 在调用时总是返回空的。这是我目前所拥有的:

MainPage.xaml(绑定(bind)到具有子 TimesheetViewModel 可观察集合的 MainViewModel):

<GridView 
    x:Name="itemGridView"
    IsItemClickEnabled="True"
    ItemsSource="{Binding Timesheets}"
    ItemTemplate="{StaticResource TimesheetTemplate}" 
    Margin="10"
    Grid.Column="0"
    SelectionMode="Multiple"
    helpers:ItemClickCommand.Command="{Binding NavigateTimesheetCommand}" RenderTransformOrigin="0.738,0.55"  >
    <GridView.ItemContainerStyle>
        <Style TargetType="GridViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
        </Style>
    </GridView.ItemContainerStyle>

</GridView>

MainViewModel(从完整代码中删减):

public class MainViewModel : ViewModelBase
{
    private readonly IDataService _dataService;
    private readonly INavigationService _navigationService;

    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel(IDataService dataService, INavigationService navigationService)
    {
        _dataService = dataService;
        _navigationService = navigationService;

        Timesheets = new ObservableCollection<TimesheetViewModel>();
        ExecuteRefreshCommand();

    }

    public ObservableCollection<TimesheetViewModel> Timesheets
    {
        get;
        private set;
    }

    public IEnumerable<TimesheetViewModel> SelectedTimesheets
    {
        get { return Timesheets.Where(o => o.IsSelected); }
    }

    private async void ExecuteRefreshCommand()
    {
        var timesheets = await _dataService.GetTimesheets("domain\\user");

        if (timesheets != null)
        {
            Timesheets.Clear();

            foreach (var timesheet in timesheets)
            {
                Timesheets.Add(new TimesheetViewModel(timesheet));
            }

        }
    }
}

时间 TableView 模型:

public class TimesheetViewModel: ViewModelBase
{

    public bool IsSelected { get; set; }

    public Timesheet Model
    {
        get;
        private set;
    }

    public TimesheetViewModel(Timesheet model)
    {
        Model = model;

    }
}

如果我手动设置 IsSelected 属性,则 SelectedTimesheets lambda 起作用,因此问题出在 XAML 与 IsSelected 属性的绑定(bind)中。

如有任何帮助,我们将不胜感激。

最佳答案

当然,我知道你的意思。太糟糕了,这不是自动的,但事实并非如此。该解决方案涉及一个简单的自定义 GridView,它继承自 GridView。没有什么太疯狂的,也就是说,如果你让它沉入其中。这是代码,我刚刚测试过它:

这是您的 XAML:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Grid.ColumnDefinitions >
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <local:MyGridView ItemsSource="{Binding Items}" SelectionMode="Multiple"
                      BindableSelectedItems="{Binding Selected}" />
    <local:MyGridView Grid.Column="1" ItemsSource="{Binding Selected}" />
</Grid>

这是您的 View 模型( super 简化):

public class ViewModel
{
    ObservableCollection<string> m_Items
        = new ObservableCollection<string>(Enumerable.Range(1, 100).Select(x => x.ToString()));
    public ObservableCollection<string> Items { get { return m_Items; } }

    ObservableCollection<object> m_Selected = new ObservableCollection<object>();
    public ObservableCollection<object> Selected { get { return m_Selected; } }
}

这是您的自定义 GridView :

public class MyGridView : GridView
{
    public ObservableCollection<object> BindableSelectedItems
    {
        get { return GetValue(BindableSelectedItemsProperty) as ObservableCollection<object>; }
        set { SetValue(BindableSelectedItemsProperty, value as ObservableCollection<object>); }
    }
    public static readonly DependencyProperty BindableSelectedItemsProperty =
        DependencyProperty.Register("BindableSelectedItems",
        typeof(ObservableCollection<object>), typeof(MyGridView),
        new PropertyMetadata(null, (s, e) =>
        {
            (s as MyGridView).SelectionChanged -= (s as MyGridView).MyGridView_SelectionChanged;
            (s as MyGridView).SelectionChanged += (s as MyGridView).MyGridView_SelectionChanged;
        }));
    void MyGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (BindableSelectedItems == null)
            return;
        foreach (var item in BindableSelectedItems.Where(x => !this.SelectedItems.Contains(x)).ToArray())
            BindableSelectedItems.Remove(item);
        foreach (var item in this.SelectedItems.Where(x => !BindableSelectedItems.Contains(x)))
            BindableSelectedItems.Add(item);
    }
}

只有一个新属性 BindableSelectedItems

祝你好运!

关于c# - 在 Windows App Store Gridview 中迭代选定的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18359366/

相关文章:

asp.net - 修改Asp gridview boundfield

c# - 模板字段消失

xaml - 项目模板中的 ListView 视觉状态管理器(WinRT、Metro、XAML)

xaml - 无法使用 x :Bind in DataTemplates - generates XAML error 绑定(bind)到按钮事件

winrt-xaml - WinRT xaml/c# 从 GoBack 页面返回导航参数

C# 如何将两个或多个整数转换为日期?

javascript - Knockout-3.2.0 - 内部列表 <object> 推送问题

c# - 在 c# 中使用 mysql 时计算受影响的行数

c# - 将文本分数转换为小数

asp.net - 如何使用 ObjectDataSource 和 TemplateFields 在 GridView 上排序