DataGrid.SelectedItems MVVM

时间:2012-07-04 15:49:18

标签: c# .net wpf xaml mvvm

我在MVVM模式上开发了我的UI,现在仍然坚持获取SelectedItems。你可以修改我的XAML并提供示例如何让它们进入ViewModel类。

<xcdg:DataGridControl Name="ResultGrid" ItemsSource="{Binding Results}"  Height="295" HorizontalAlignment="Left" Margin="6,25,0,0" VerticalAlignment="Top" Width="1041" ReadOnly="True">
                    <xcdg:DataGridControl.View>
                        <xcdg:TableflowView UseDefaultHeadersFooters="False">
                            <xcdg:TableflowView.FixedHeaders>
                                <DataTemplate>
                                    <xcdg:ColumnManagerRow />
                                </DataTemplate>
                            </xcdg:TableflowView.FixedHeaders>
                        </xcdg:TableflowView>
                    </xcdg:DataGridControl.View>
                </xcdg:DataGridControl>

3 个答案:

答案 0 :(得分:3)

您可以使用附加行为来获取/设置SelectedItems到datagrid。

我在Metro应用程序中遇到了类似的问题,因此必须自己编写。

以下是链接

http://www.codeproject.com/Articles/412417/Managing-Multiple-selection-in-View-Model-NET-Metr

虽然我是为metro应用程序编写的,但可以在WPF / Silverlight中修改相同的解决方案。

    public class MultiSelectBehavior : Behavior<ListViewBase>
        {
            #region SelectedItems Attached Property
            public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(
                "SelectedItems",
                typeof(ObservableCollection<object>),
                typeof(MultiSelectBehavior),
                new PropertyMetadata(new ObservableCollection<object>(), PropertyChangedCallback));

            #endregion

            #region private
            private bool _selectionChangedInProgress; // Flag to avoid infinite loop if same viewmodel is shared by multiple controls
            #endregion

            public MultiSelectBehavior()
            {
                SelectedItems = new ObservableCollection<object>();
            }

            public ObservableCollection<object> SelectedItems
            {
                get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
                set { SetValue(SelectedItemsProperty, value); }
            }

            protected override void OnAttached()
            {
                base.OnAttached();
                AssociatedObject.SelectionChanged += OnSelectionChanged;
            }

            protected override void OnDetaching()
            {
                base.OnDetaching();
                AssociatedObject.SelectionChanged -= OnSelectionChanged;
            }

            private static void PropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
            {
                NotifyCollectionChangedEventHandler handler =  (s, e) => SelectedItemsChanged(sender, e);
                if (args.OldValue is ObservableCollection<object>)
                {
                    (args.OldValue as ObservableCollection<object>).CollectionChanged -= handler;
                }

                if (args.NewValue is ObservableCollection<object>)
                {
                    (args.NewValue as ObservableCollection<object>).CollectionChanged += handler;
                }
            }

            private static void SelectedItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
            {
                if (sender is MultiSelectBehavior)
                {
                    var listViewBase = (sender as MultiSelectBehavior).AssociatedObject;

                    var listSelectedItems = listViewBase.SelectedItems;
                    if (e.OldItems != null)
                    {
                        foreach (var item in e.OldItems)
                        {
                            if (listSelectedItems.Contains(item))
                            {
                                listSelectedItems.Remove(item);
                            }
                        }
                    }

                    if (e.NewItems != null)
                    {
                        foreach (var item in e.NewItems)
                        {
                            if (!listSelectedItems.Contains(item))
                            {
                                listSelectedItems.Add(item);
                            }
                        }
                    }
                }
            }

            private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (_selectionChangedInProgress) return;
                _selectionChangedInProgress = true;
                foreach (var item in e.RemovedItems)
                {
                    if (SelectedItems.Contains(item))
                    {
                        SelectedItems.Remove(item);
                    }
                }

                foreach (var item in e.AddedItems)
                {
                    if (!SelectedItems.Contains(item))
                    {
                        SelectedItems.Add(item);
                    }
                }
                _selectionChangedInProgress = false;
            }
        }

答案 1 :(得分:1)

如果您想要多重选择并且想要获得这些选定的项目,可能还有更多工作要做。您是否要存储所选项目,并且在执行某些操作(点击按钮或类似内容)时,您想要使用这些selectedItems并对它们执行某些操作吗?

这里有一个很好的例子:

Get SelectedItems From DataGrid Using MVVM

它声明它是为Silverlight设计的,但它也适用于带MVVM的WPF。

也许这是一种更直接的方法:

Get Selected items in a WPF datagrid

答案 2 :(得分:-1)

创建附加行为以连接每个只读集合或非依赖项属性将需要大量工作。一个简单的解决方案是使用视图将引用传递给视图模型。

Private ReadOnly Property ViewModel As MyViewModel
    Get
        Return DirectCast(DataContext, MyViewModel)
    End Get
End Property

Private Sub MyView_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
    If ViewModel.SelectedItems Is Nothing Then
        ViewModel.SelectedItems = MyDataGrid.SelectedItems 
    End If
End Sub