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

Attached ビヘイビアーを使用して、SelectedItems をデータグリッドに取得/設定できます。

Metro アプリで同様の問題に直面していたので、自分で作成する必要がありました。

以下はリンクです

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

私は地下鉄アプリ用に書いていましたが、同じソリューションを 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 に答える