1

我在 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>
4

3 回答 3

3

您可以使用附加行为将 SelectedItems 获取/设置为数据网格。

我在 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;
            }
        }
于 2012-07-04T16:05:31.653 回答
1

如果您想要多选并且想要获得那些选定的项目,可能还有更多工作要做。您是否要存储选定的项目,并且在执行某些操作(单击按钮或类似的操作)时,您想使用这些 selectedItems 并对其进行处理?

这里有一个很好的例子:

使用 MVVM 从 DataGrid 中获取 SelectedItems

它声明它是为 Silverlight 设计的,但它也可以在带有 MVVM 的 WPF 中工作。

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

获取 WPF 数据网格中的选定项目

于 2012-07-04T15:57:43.637 回答
-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
于 2016-04-21T18:00:03.153 回答