WPFのDataGridに独自型をバインドし、AutoGenerateColumn
をtrue
に設定しています。このデータの特定列を非表示にしたいため、AutoGeneratingColumn
イベントをViewModelでハンドルして非表示にすることを考えました。
そこでEventToReactiveCommand
をxamlに記述したのですが、このコマンドのSubscribe
が実行されません。コードビハインドでハンドルするとイベント自体は起きているようなのですが、なぜVM側で購読がうまくできないんでしょう?
xaml
xaml
1<Window x:Class="BlankCoreApp1.Views.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:prism="http://prismlibrary.com/" 5 xmlns:local="clr-namespace:BlankCoreApp1" 6 xmlns:i="http://schemas.microsoft.com/xaml/behaviors" 7 xmlns:rp="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF" 8 prism:ViewModelLocator.AutoWireViewModel="True" 9 Title="{Binding Title}" Height="350" Width="525" > 10 <Grid> 11 <DataGrid ItemsSource="{Binding MyData}" AutoGenerateColumns="True" 12 AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" 13 AutoGeneratedColumns="DataGrid_AutoGeneratedColumns" 14 > 15 <i:Interaction.Triggers> 16 <i:EventTrigger EventName="AutoGeneratingColumn"> 17 <rp:EventToReactiveCommand Command="{Binding AutoGeneratingColumnCommand}"> 18 <local:DataGridAutoGeneratingColumnEventConverter/> 19 </rp:EventToReactiveCommand> 20 </i:EventTrigger> 21 </i:Interaction.Triggers> 22 </DataGrid> 23 </Grid> 24</Window>
Viewのコード
c#
1using System.Windows; 2 3namespace BlankCoreApp1.Views 4{ 5 /// <summary> 6 /// Interaction logic for MainWindow.xaml 7 /// </summary> 8 public partial class MainWindow : Window 9 { 10 public MainWindow() 11 { 12 System.Diagnostics.Debug.WriteLine(nameof(MainWindow)); 13 InitializeComponent(); 14 System.Diagnostics.Debug.WriteLine(nameof(InitializeComponent)); 15 } 16 17 private void DataGrid_AutoGeneratingColumn(object sender, System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs e) 18 { 19 System.Diagnostics.Debug.WriteLine(e.Column.Header.ToString()); 20 } 21 22 private void DataGrid_AutoGeneratedColumns(object sender, System.EventArgs e) 23 { 24 System.Diagnostics.Debug.WriteLine(nameof(DataGrid_AutoGeneratedColumns)); 25 } 26 } 27}
ViewModelのコード
c#
1using Prism.Mvvm; 2using Reactive.Bindings; 3using System.Windows.Controls; 4using System.Collections.ObjectModel; 5using System.Linq; 6 7namespace BlankCoreApp1.ViewModels 8{ 9 public class MainWindowViewModel : BindableBase 10 { 11 private string _title = "Prism Application"; 12 public string Title 13 { 14 get { return _title; } 15 set { SetProperty(ref _title, value); } 16 } 17 18 public ReactiveCollection<MyDataClass> MyData { get; } 19 public ReactiveCommand<DataGridColumn> AutoGeneratingColumnCommand { get; } 20 public MainWindowViewModel() 21 { 22 System.Diagnostics.Debug.WriteLine(nameof(MainWindowViewModel)); 23 MyData = new ReactiveCollection<MyDataClass>(); 24 MyData.AddRange(Enumerable.Range(1, 10).Select(_ => new MyDataClass("a", "b", "C")).ToArray()); 25 AutoGeneratingColumnCommand = new ReactiveCommand<DataGridColumn>(). 26 WithSubscribe(c => 27 { 28 // ここに来ない 29System.Diagnostics.Debug.WriteLine(nameof(AutoGeneratingColumnCommand)); 30 }); 31 } 32 } 33}
データとイベントのコンバーター
c#
1using Reactive.Bindings.Interactivity; 2using System; 3using System.Linq; 4using System.Reactive.Linq; 5using System.Windows.Controls; 6 7namespace BlankCoreApp1 8{ 9 public class DataGridAutoGeneratingColumnEventConverter : ReactiveConverter<DataGridAutoGeneratingColumnEventArgs, DataGridColumn> 10 { 11 protected override IObservable<DataGridColumn> OnConvert(IObservable<DataGridAutoGeneratingColumnEventArgs> source) 12 { 13 System.Diagnostics.Debug.WriteLine(nameof(DataGridAutoGeneratingColumnEventConverter)); 14 return source.Select(s => s.Column); 15 } 16 } 17 18 public record MyDataClass(string Id, string Address, string HideColumn); 19}
目的
VMでやりたい理由は以下です。
AutoGenerateColumn
をfalse
にするのは、開発中にデータ項目が増えたり減ったりするたびにxamlの列定義をいじりたくないためやりたくない- バインドしているデータは表示にしか使わないためVMの内部クラスとしたいので、コードビハインドで列インデックスや列名指定をしたくない
環境
C# 9.0 / NET 5.0
ReactiveProperty / ReactiveProperty.WPF は version 7.11
回答1件
あなたの回答
tips
プレビュー