C# DataGrid.SelectedItems MVVM

C# DataGrid.SelectedItems MVVM,c#,.net,wpf,xaml,mvvm,C#,.net,Wpf,Xaml,Mvvm,我在MVVM模式上开发了我的UI,现在我坚持使用SelectedItems。请您修改我的XAML,并提供如何在DE ViewModel类中获取它们的示例 <xcdg:DataGridControl Name="ResultGrid" ItemsSource="{Binding Results}" Height="295" HorizontalAlignment="Left" Margin="6,25,0,0" VerticalAlignment="Top" Width="1041" Re

我在MVVM模式上开发了我的UI,现在我坚持使用SelectedItems。请您修改我的XAML,并提供如何在DE 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>

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

这里有一个很好的例子:

它声明它是为Silverlight设计的,但它也将在WPF和MVVM中工作

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


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

我在Metro应用程序中遇到了类似的问题,所以我不得不自己编写

下面是链接

虽然我为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;
            }
        }
公共类多选行为:行为
{
#区域SelectedItems附加属性
公共静态只读DependencyProperty SelectedItemsProperty=DependencyProperty.Register(
“SelectedItems”,
类型(可观测采集),
类型(多选行为),
新的PropertyMetadata(新的ObservableCollection(),PropertyChangedCallback));
#端区
#地区私人
private bool _selectionChangedInProgress;//如果同一视图模型由多个控件共享,则避免无限循环的标志
#端区
公共多选行为()
{
SelectedItems=新的ObservableCollection();
}
公共可观测集合SelectedItems
{
get{return(ObservableCollection)GetValue(SelectedItemsProperty);}
set{SetValue(selecteditemsprroperty,value);}
}
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.SelectionChanged+=OnSelectionChanged;
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
AssociatedObject.SelectionChanged-=OnSelectionChanged;
}
私有静态无效属性ChangedCallback(DependencyObject发送方,DependencyPropertyChangedEventArgs参数)
{
NotifyCollectionChangedEventHandler处理程序=(s,e)=>SelectedItemsChanged(发送方,e);
如果(args.OldValue为ObservableCollection)
{
(args.OldValue作为ObservableCollection).CollectionChanged-=处理程序;
}
if(args.NewValue是ObservableCollection)
{
(args.NewValue作为ObservableCollection).CollectionChanged+=处理程序;
}
}
私有静态void SelectedItemsChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
如果(发送方是多选行为)
{
变量listViewBase=(发送方为MultiSelectBehavior)。AssociatedObject;
var listSelectedItems=listViewBase.SelectedItems;
如果(例如,OldItems!=null)
{
foreach(e.OldItems中的var项)
{
如果(listSelectedItems.Contains(项目))
{
listSelectedItems.Remove(项目);
}
}
}
如果(如NewItems!=null)
{
foreach(e.NewItems中的var项)
{
如果(!listSelectedItems.Contains(项))
{
listSelectedItems.Add(项目);
}
}
}
}
}
SelectionChanged上的私有无效(对象发送方,SelectionChangedEventArgs e)
{
如果(_selectionChangedInProgress)返回;
_selectionChangedInProgress=true;
foreach(e.RemovedItems中的var项)
{
如果(选择编辑项包含(项))
{
选择编辑项。删除(项);
}
}
foreach(e.AddedItems中的变量项)
{
如果(!SelectedItems.Contains(项))
{
选择编辑项。添加(项);
}
}
_selectionChangedInProgress=false;
}
}

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

私有只读属性ViewModel作为MyViewModel
得到
返回DirectCast(DataContext,MyViewModel)
结束
端属性
私有子MyView_Loaded(发件人作为对象,e作为RoutedEventArgs)处理我。Loaded
如果ViewModel.SelectedItems为空,则
ViewModel.SelectedItems=MyDataGrid.SelectedItems
如果结束
端接头

您是只想获取selecteditems,还是还想从viewmodel设置selecteditems?此外,您希望在进行选择时或仅在调用按钮命令时获得selecteditems吗?