2014年4月18日金曜日

[WPF][Silverlight][C#]MVVM で DataGrid の SelectedItems を取得する

ことは出来なさそうです。
一番手っ取り早いのは、Item に選択状態プロパティを追加して DataGridRow の IsSelected にバインドさせることですかねー。

View側を簡単に書いてみます。

    <Window.DataContext>
        <vm:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Path=List}" AutoGenerateColumns="False" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="No" Binding="{Binding Path=No}" />
                <DataGridTextColumn Header="Date" Binding="{Binding Path=Date, StringFormat=yyyy/MM/dd}" />
            </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected}" />
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
    </Grid>


ViewModel 側はこんな感じ。

    public class ItemViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        public int No { get; set; }
        public DateTime Date { get { return DateTime.Now.AddDays(No); } }

        private bool isSelected;
        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value; OnPropertyChanged("IsSelected"); }
        }

    }

    public class MainWindowViewModel
    {
        public List<ItemViewModel> List { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public MainWindowViewModel()
        {
            List = new List<ItemViewModel>();
            for (int i = 0; i < 100; i++)
                List.Add(new ItemViewModel() { No = i });
        }

    }

これが一番簡単だと思います。



2 件のコメント:

  1. この方法を参考に実装してみたのですが
    ある1行を選択→
    他のコントロールを選択してデータグリッドを非アクティブに→
    データグリッド上にカーソルを移し非アクティブのままマウスホイールでスクロール→
    最初に選択した行がスクロールされて見えなくなってから他の行を選択
    とすると、最小に選択した行のIsSelectedがfalseになってくれないです。
    IsSelectedのBindingは見えない行には適用されないのでしょうか??
    .NET 4.5です。
    CanContentScrollをfalseにすると問題が起きなくなるので、UIの仮想化?が影響しているかもしれません。

    返信削除
  2. UIが仮想化されているのが原因でしょう。こういうことかと
    http://qiita.com/wonderful_panda/items/36bf500094cc42f7ea97

    返信削除