###環境
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}

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/12 06:37