質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

7161閲覧

WPF(MVVM)、Prism+ReactivePropertyの環境でDataGird上のセルの値が変更されたときの変更通知をCollection側で捕捉したい。

mayomayo

総合スコア7

DataGrid

GUIの一種であり、データを表の形式でみることが可能です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2017/05/10 02:38

###環境
Visual Studio 2017 WPF(C#)
.Net Framework 4.6.2
Prism.Core 6.3.0 (NuGetよりインストール)
ReactiveProperty 3.6.0 (NuGetよりインストール)

###実現したいこと
DataGird上で年齢のカラムが変更されフォーカスがロストした際に
TextBoxに年齢を集計して表示したいです。

###問題点
DataGird上でデータを変更した際にカラム用のViewModel及びModelでは変更通知が捕捉できますが
行データ用のCollectionのほうで変更通知を捕捉したいのですが捕捉方法がわかりません。

C#

1using Prism.Mvvm; 2 3namespace DataGridSampleProject.Models 4{ 5 public class PersonModel : BindableBase 6 { 7 private string name; 8 9 public string Name 10 { 11 get { return this.name; } 12 set { this.SetProperty(ref this.name, value); } 13 } 14 15 private int age; 16 17 public int Age 18 { 19 get { return this.age; } 20 set { this.SetProperty(ref this.age, value); } 21 } 22 } 23}

C#

1using System.Collections.ObjectModel; 2 3namespace DataGridSampleProject.Models 4{ 5 public class PeopleModel 6 { 7 public ObservableCollection<PersonModel> People { get; private set; } 8 9 public PeopleModel() 10 { 11 this.People = new ObservableCollection<PersonModel>(); 12 13 this.People.Add(new PersonModel { Name = "一郎", Age = 44 }); 14 this.People.Add(new PersonModel { Name = "次郎", Age = 38 }); 15 this.People.Add(new PersonModel { Name = "三郎", Age = 29 }); 16 this.People.Add(new PersonModel { Name = "史郎", Age = 25 }); 17 } 18 } 19}

C#

1using Reactive.Bindings; 2using Reactive.Bindings.Extensions; 3 4using DataGridSampleProject.Models; 5 6namespace DataGridSampleProject.ViewModels 7{ 8 public class PersonViewModel 9 { 10 public ReactiveProperty<string> Name { get; private set; } 11 12 public ReactiveProperty<string> Age { get; private set; } 13 14 public PersonViewModel(PersonModel model) 15 { 16 this.Name = model.ToReactivePropertyAsSynchronized(x => x.Name); 17 18 this.Age = model.ToReactivePropertyAsSynchronized 19 ( 20 x => x.Age, 21 convert: x => x.ToString(), 22 convertBack: x => 23 { 24 try 25 { 26 return int.Parse(x); 27 } 28 catch 29 { 30 return -1; 31 } 32 } 33 ); 34 } 35 } 36}

C#

1using System.Reactive.Disposables; 2using System.Linq; 3 4using Reactive.Bindings; 5using Reactive.Bindings.Extensions; 6 7using DataGridSampleProject.Models; 8 9namespace DataGridSampleProject.ViewModels 10{ 11 public class PeopleViewModel 12 { 13 private CompositeDisposable Disposeable { get; } = new CompositeDisposable(); 14 15 public ReadOnlyReactiveCollection<PersonViewModel> People { get; private set; } 16 17 private string total; 18 19 public string Total 20 { 21 get 22 { 23 return this.People.Sum(x => long.Parse(x.Age.Value.ToString())).ToString(); 24 } 25 set 26 { 27 this.total = value; 28 } 29 } 30 31 public PeopleViewModel() 32 { 33 var m = new PeopleModel(); 34 35 this.People = m.People.ToReadOnlyReactiveCollection(x => new PersonViewModel(x)).AddTo(this.Disposeable); 36 } 37 } 38}

XAML

1<Window x:Class="DataGridSampleProject.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:DataGridSampleProject.Views" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="800" Width="1280" WindowStartupLocation="CenterScreen"> 9 <StackPanel> 10 <DataGrid AutoGenerateColumns="False" 11 GridLinesVisibility="All" 12 VerticalGridLinesBrush="Silver" 13 HorizontalGridLinesBrush="Silver" 14 HeadersVisibility="All" 15 RowHeaderWidth="31.4" 16 RowBackground="White" 17 AlternatingRowBackground="AliceBlue" 18 SelectionMode="Single" 19 SelectionUnit="FullRow" 20 ItemsSource="{Binding Path=People}" 21 HorizontalScrollBarVisibility="Auto" 22 VerticalScrollBarVisibility="Visible"> 23 <DataGrid.Columns> 24 <!-- 名前 --> 25 <DataGridTemplateColumn Width="182"> 26 <DataGridTemplateColumn.HeaderStyle> 27 <Style TargetType="DataGridColumnHeader"> 28 <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 29 </Style> 30 </DataGridTemplateColumn.HeaderStyle> 31 <DataGridTemplateColumn.HeaderTemplate> 32 <DataTemplate> 33 <TextBlock Text="名前" /> 34 </DataTemplate> 35 </DataGridTemplateColumn.HeaderTemplate> 36 <DataGridTemplateColumn.CellTemplate> 37 <DataTemplate> 38 <TextBlock Text="{Binding Path=Name.Value, Mode=OneWay}" TextAlignment="Left" Height="24" /> 39 </DataTemplate> 40 </DataGridTemplateColumn.CellTemplate> 41 <DataGridTemplateColumn.CellEditingTemplate> 42 <DataTemplate> 43 <TextBox Text="{Binding Path=Name.Value, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 44 TextAlignment="Left" Height="24" /> 45 </DataTemplate> 46 </DataGridTemplateColumn.CellEditingTemplate> 47 </DataGridTemplateColumn> 48 <!-- 年齢 --> 49 <DataGridTemplateColumn Width="182"> 50 <DataGridTemplateColumn.HeaderStyle> 51 <Style TargetType="DataGridColumnHeader"> 52 <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 53 </Style> 54 </DataGridTemplateColumn.HeaderStyle> 55 <DataGridTemplateColumn.HeaderTemplate> 56 <DataTemplate> 57 <TextBlock Text="年齢" /> 58 </DataTemplate> 59 </DataGridTemplateColumn.HeaderTemplate> 60 <DataGridTemplateColumn.CellTemplate> 61 <DataTemplate> 62 <TextBlock Text="{Binding Path=Age.Value, Mode=OneWay}" TextAlignment="Right" Height="24" /> 63 </DataTemplate> 64 </DataGridTemplateColumn.CellTemplate> 65 <DataGridTemplateColumn.CellEditingTemplate> 66 <DataTemplate> 67 <TextBox Text="{Binding Path=Age.Value, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 68 TextAlignment="Right" Height="24" /> 69 </DataTemplate> 70 </DataGridTemplateColumn.CellEditingTemplate> 71 </DataGridTemplateColumn> 72 </DataGrid.Columns> 73 </DataGrid> 74 <TextBox Text="{Binding Path=Total}" /> 75 </StackPanel> 76</Window>

C#

1using System.Windows; 2 3using DataGridSampleProject.ViewModels; 4 5namespace DataGridSampleProject.Views 6{ 7 /// <summary> 8 /// MainWindow.xaml の相互作用ロジック 9 /// </summary> 10 public partial class MainWindow : Window 11 { 12 public MainWindow() 13 { 14 this.InitializeComponent(); 15 16 this.DataContext = new PeopleViewModel(); 17 } 18 } 19}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

合計表示できたので、貼っておきます

XAML

1<Window x:Class="DataGridSampleProject.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:DataGridSampleProject" 7 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 8 mc:Ignorable="d" 9 Title="MainWindow" Height="800" Width="1280" WindowStartupLocation="CenterScreen"> 10 <StackPanel> 11 <DataGrid AutoGenerateColumns="False" 12 GridLinesVisibility="All" 13 VerticalGridLinesBrush="Silver" 14 HorizontalGridLinesBrush="Silver" 15 HeadersVisibility="All" 16 RowHeaderWidth="31.4" 17 RowBackground="White" 18 AlternatingRowBackground="AliceBlue" 19 SelectionMode="Single" 20 SelectionUnit="FullRow" 21 ItemsSource="{Binding Path=People}" 22 HorizontalScrollBarVisibility="Auto" 23 VerticalScrollBarVisibility="Visible"> 24 25 <i:Interaction.Behaviors> 26 <local:DataGridBehavior/> 27 </i:Interaction.Behaviors> 28 29 <DataGrid.Columns> 30 <!-- 名前 --> 31 <DataGridTemplateColumn Width="182"> 32 <DataGridTemplateColumn.HeaderStyle> 33 <Style TargetType="DataGridColumnHeader"> 34 <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 35 </Style> 36 </DataGridTemplateColumn.HeaderStyle> 37 <DataGridTemplateColumn.HeaderTemplate> 38 <DataTemplate> 39 <TextBlock Text="名前" /> 40 </DataTemplate> 41 </DataGridTemplateColumn.HeaderTemplate> 42 <DataGridTemplateColumn.CellTemplate> 43 <DataTemplate> 44 <TextBlock Text="{Binding Path=Name.Value, Mode=OneWay}" TextAlignment="Left" Height="24" /> 45 </DataTemplate> 46 </DataGridTemplateColumn.CellTemplate> 47 <DataGridTemplateColumn.CellEditingTemplate> 48 <DataTemplate> 49 <TextBox Text="{Binding Path=Name.Value, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 50 TextAlignment="Left" Height="24" /> 51 </DataTemplate> 52 </DataGridTemplateColumn.CellEditingTemplate> 53 </DataGridTemplateColumn> 54 <!-- 年齢 --> 55 <DataGridTemplateColumn Width="182"> 56 <DataGridTemplateColumn.HeaderStyle> 57 <Style TargetType="DataGridColumnHeader"> 58 <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 59 </Style> 60 </DataGridTemplateColumn.HeaderStyle> 61 <DataGridTemplateColumn.HeaderTemplate> 62 <DataTemplate> 63 <TextBlock Text="年齢" /> 64 </DataTemplate> 65 </DataGridTemplateColumn.HeaderTemplate> 66 <DataGridTemplateColumn.CellTemplate> 67 <DataTemplate> 68 <TextBlock Text="{Binding Path=Age.Value, Mode=OneWay}" TextAlignment="Right" Height="24" /> 69 </DataTemplate> 70 </DataGridTemplateColumn.CellTemplate> 71 <DataGridTemplateColumn.CellEditingTemplate> 72 <DataTemplate> 73 <TextBox Text="{Binding Path=Age.Value, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" 74 TextAlignment="Right" Height="24" /> 75 </DataTemplate> 76 </DataGridTemplateColumn.CellEditingTemplate> 77 </DataGridTemplateColumn> 78 </DataGrid.Columns> 79 </DataGrid> 80 <TextBox Text="{Binding Path=Total}" /> 81 </StackPanel> 82</Window>

using

1using Reactive.Bindings; 2using Reactive.Bindings.Extensions; 3using System; 4using System.ComponentModel; 5using System.Linq; 6using System.Reactive.Disposables; 7using System.Runtime.CompilerServices; 8 9namespace DataGridSampleProject.ViewModels 10{ 11 public class PeopleViewModel : INotifyPropertyChanged 12 { 13 private CompositeDisposable Disposeable { get; } = new CompositeDisposable(); 14 15 public ReadOnlyReactiveCollection<PersonViewModel> People { get; private set; } 16 17 private string total; 18 19 public string Total 20 { 21 get 22 { 23 return this.People.Sum(x => long.Parse(x.Age.Value.ToString())).ToString(); 24 } 25 set 26 { 27 this.total = value; 28 } 29 } 30 31 public PeopleViewModel() 32 { 33 var m = new PeopleModel(); 34 this.People = m.People.ToReadOnlyReactiveCollection(x => new PersonViewModel(x)).AddTo(this.Disposeable); 35 } 36 37 public event PropertyChangedEventHandler PropertyChanged; 38 39 public void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 40 { 41 if (PropertyChanged != null) 42 { 43 PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 44 } 45 } 46 } 47}
using System.Windows.Controls; using System.Windows.Interactivity; namespace DataGridSampleProject { public class DataGridBehavior : Behavior<DataGrid> { private bool _isEditEnding = false; protected override void OnAttached() { base.OnAttached(); this.AssociatedObject.SelectedCellsChanged += AssociatedObject_SelectedCellsChanged; this.AssociatedObject.CellEditEnding += AssociatedObject_CellEditEnding; } protected override void OnDetaching() { base.OnDetaching(); this.AssociatedObject.SelectedCellsChanged -= AssociatedObject_SelectedCellsChanged; this.AssociatedObject.CellEditEnding -= AssociatedObject_CellEditEnding; } private void AssociatedObject_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) { _isEditEnding = true; } private void AssociatedObject_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { if (_isEditEnding) { var dg = sender as DataGrid; var vm = dg.DataContext as ViewModels.PeopleViewModel; vm.NotifyPropertyChanged("Total"); _isEditEnding = false; } } } }

投稿2017/05/11 08:32

dn315

総合スコア201

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mayomayo

2017/05/12 06:37

コメントが遅くなり申し訳ありません。 回答いただきありがとうございます。確かにBehaviorを使えば想定通りの動きが出来ました。 ありがとうございます!
guest

0

質問の答えにならないかもしれませんが
Behaviorを使って
CellEditEndingかSelectedCellsChangedあたりの
イベントで処理してみてはいかがでしょうか

【WPF】Behaviorで快適WPFライフ

投稿2017/05/11 04:22

dn315

総合スコア201

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問