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

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

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

ReactiveX(Rx、Reactive Extensions)は、リアクティブプログラミングが可能なライブラリ。Java/Android用のRxJava、JavaScript用のRxJSなどさまざまな言語向けに実装されています。

C#

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

WPF

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

Q&A

解決済

1回答

3285閲覧

DataGridのAutoGeneratingColumnイベントをEventToReactiveCommandで購読できない

ry188472

総合スコア74

ReactiveX

ReactiveX(Rx、Reactive Extensions)は、リアクティブプログラミングが可能なライブラリ。Java/Android用のRxJava、JavaScript用のRxJSなどさまざまな言語向けに実装されています。

C#

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

WPF

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

0グッド

0クリップ

投稿2021/10/05 08:40

WPFのDataGridに独自型をバインドし、AutoGenerateColumntrueに設定しています。このデータの特定列を非表示にしたいため、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でやりたい理由は以下です。

  • AutoGenerateColumnfalseにするのは、開発中にデータ項目が増えたり減ったりするたびにxamlの列定義をいじりたくないためやりたくない
  • バインドしているデータは表示にしか使わないためVMの内部クラスとしたいので、コードビハインドで列インデックスや列名指定をしたくない

環境

C# 9.0 / NET 5.0
ReactiveProperty / ReactiveProperty.WPF は version 7.11

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

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

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

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

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

TN8001

2021/10/05 13:04

仕様なのか不具合なのかわかりませんが、MyDataの初期化を遅らせる(Loaded以降?)と、呼ばれるようになりました(RaisePropertyChangedしてください) 直接聞いてみたらどうですか? [Issues · runceel/ReactiveProperty](https://github.com/runceel/ReactiveProperty/issues
ry188472

2021/10/06 00:19

MyDataの初期化が完了するのは実際には不定(VMでModelクラスから通信処理してデータ取得するため)なのでその方法は難しそうです。検証ありがとうございました!
guest

回答1

0

ベストアンサー

SourceObjectを指定することで解決しませんか?

xaml

1<DataGrid 2 x:Name="dataGrid" 3 ItemsSource="{Binding MyData}" 4 AutoGenerateColumns="True"> 5 <i:Interaction.Triggers> 6 <i:EventTrigger EventName="AutoGeneratingColumn" SourceObject="{Binding ElementName=dataGrid}">

投稿2021/10/05 13:07

soi013

総合スコア149

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

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

ry188472

2021/10/06 00:19

こちらで解決できました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問