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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

WPF

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

Q&A

解決済

1回答

2395閲覧

WPFでコントロールを追加したときにイベントを発生させたい

Lyricania0220

総合スコア11

C#

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

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

WPF

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

1グッド

0クリップ

投稿2021/06/03 12:44

###前提・実現したいこと
WPFコントロール追加時にそのイベントを取得し、そこでログに書き出すなりの動作を行いたいです。
下記はWindowsFormsですが、上記の動作はできています。
しかし、WPFでは該当の処理を実装できませんでした。

WPFでも、WindowsFormsのControlAddedイベントのようにコントロールを追加時にイベントを発生させたいです。
######・WindowsForms

C#

1using System.Windows.Forms; 2 3namespace WindowsFormsApp1 4{ 5 public partial class Form1 : Form 6 { 7 public Form1() 8 { 9 InitializeComponent(); 10 11 this.button1.Click += button1_Click; 12 EventRegister(this); 13 } 14 15 /// <summary> 16 /// 指定したコントロールとその全ての子コントロールにイベントを登録します。 17 /// </summary> 18 /// <param name="control"></param> 19 private void EventRegister(Control control) 20 { 21 control.ControlAdded += Control_ControlAdded; 22 control.MouseDown += Control_MouseDown; 23 24 // 子コントロールにもイベントを登録する 25 foreach (Control child in control.Controls) 26 { 27 EventRegister(child); 28 } 29 } 30 31 private void button1_Click(object sender, System.EventArgs e) 32 { 33 this.panel1.Controls.Add(new Button()); 34 } 35 36 private void Control_ControlAdded(object sender, ControlEventArgs e) 37 { 38 EventRegister(e.Control); 39 } 40 41 private void Control_MouseDown(object sender, MouseEventArgs e) 42 { 43 // マウスダウンを実行したということをログに記載する 44 } 45 } 46}

######・WPF

XML

1<Window x:Class="WpfApp1.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:WpfApp1" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <WrapPanel Name="MainWrapPanel"> 10 <Button Name="button1" Content="Button" Margin="10" Height="20" Width="75"/> 11 </WrapPanel> 12</Window>

C#

1using System.Windows; 2 3namespace WpfApp1 4{ 5 /// <summary> 6 /// MainWindow.xaml の相互作用ロジック 7 /// </summary> 8 public partial class MainWindow : Window 9 { 10 public MainWindow() 11 { 12 InitializeComponent(); 13 14 this.button1.Click += Button_Click; 15 EventRegister(this); 16 } 17 18 /// <summary> 19 /// 指定したコントロールとその全ての子コントロールにイベントを登録します。 20 /// </summary> 21 /// <param name="element"></param> 22 private void EventRegister(FrameworkElement element) 23 { 24 //element.ControlAdded += Control_ControlAdded; // エラーが出る 25 element.PreviewMouseDown += Control_PreviewMouseDown; 26 27 // 子コントロールにもイベントを登録する 28 foreach (var child in LogicalTreeHelper.GetChildren(element)) 29 { 30 if (child is FrameworkElement) 31 { 32 EventRegister(child as FrameworkElement); 33 } 34 } 35 } 36 37 protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) 38 { 39 // このイベントだと、ウィンドウにコントロールが追加されたことしか取得できない 40 base.OnVisualChildrenChanged(visualAdded, visualRemoved); 41 } 42 43 private void Button_Click(object sender, RoutedEventArgs e) 44 { 45 var button = new System.Windows.Controls.Button() 46 { 47 Height = 20, 48 Width = 75, 49 Margin = new Thickness(10), 50 }; 51 MainWrapPanel.Children.Add(button); // 追加したbuttonに対してEventRegisterを実行したい 52 } 53 54 private void Control_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 55 { 56 // マウスダウンを実行したということをログに記載する 57 } 58 } 59}

###試したこと
Stack overflowMicroSoftドキュメントを参考にしてソースを組んでみましたが、WindowsFormsのようにイベントが発生しませんでした。

開発環境

.NET Framework 4.8

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

MainWrapPanelの子だけを検知できればいいのなら、WrapPanelを継承しOnVisualChildrenChangedをオーバーライドすればいいでしょう(試したことのリンク記事はそういう意味です)

ですがやりたいことって恐らくそういう意味じゃないんですよね?
どこに置いたボタン(等)でもイベントを拾いたいって意味ですよね。

WPFはルーティングイベントという大変便利な仕組みがあります。
MainWindowで一括してButton.Clickを拾うことができます。
ルーティング イベントの概要 - WPF .NET Framework | Microsoft Docs

イベントによっては(例えばButton.MouseDown)処理済みになって来ないので、トンネルイベント(Previewなんちゃら)を使用してください。

xml

1<Window 2 x:Class="Questions342011.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450" 7 Button.Click="Window_Button_Click"> 8 <WrapPanel Name="MainWrapPanel"> 9 <Button 10 Width="75" 11 Margin="10" 12 Click="AddButton_Click" 13 Content="Add" /> 14 </WrapPanel> 15</Window>

cs

1using System.Diagnostics; 2using System.Windows; 3using System.Windows.Controls; 4 5namespace Questions342011 6{ 7 public partial class MainWindow : Window 8 { 9 public MainWindow() => InitializeComponent(); 10 11 private int count; 12 private void AddButton_Click(object sender, RoutedEventArgs e) 13 { 14 var button = new Button() 15 { 16 Content = $"Button{++count}", 17 Width = 75, 18 Margin = new Thickness(10), 19 }; 20 button.Click += Button_Click; 21 MainWrapPanel.Children.Add(button); 22 } 23 24 private void Button_Click(object sender, RoutedEventArgs e) 25 { 26 Debug.WriteLine($"Button_Click: {(e.Source as Button).Content}"); 27 //e.Handled = true; // 処理済みにすると↓に来なくなるので注意 28 } 29 30 private void Window_Button_Click(object sender, RoutedEventArgs e) 31 { 32 Debug.WriteLine($"Window_Button_Click: {(e.Source as Button).Content}"); 33 } 34 } 35}

投稿2021/06/03 14:02

編集2023/07/27 14:48
TN8001

総合スコア9321

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

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

Lyricania0220

2021/06/03 14:36

返信ありがとうございます。 Stack overflowの記事読み違えていました。 OnVisualChildrenChangedはPanelを親に持つコントロールでも使えたんですね。 私がやりたかったことは、新規に追加したすべてのコントロールに対して、「EventRegister()」メソッドを用いてイベントを登録したいというものでした。 説明下手ですみません。 ですので、Panelを親に持つコントロールを継承したコントロールを作成し、OnVisualChildrenChangedをオーバライドする方法で実装しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問