🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

WPF

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

Q&A

解決済

1回答

1211閲覧

WPFアプリでホストしたコントロールをラップしたい。

MomenToufu

総合スコア10

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

XAML

XAML(Extensible Application Markup Language)はWPF、Silverlight、Windows PhoneそしてWindows Store appsでユーザーインターフェースを定義するために使われるXML言語です。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

WPF

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

0グッド

0クリップ

投稿2021/01/29 07:39

編集2021/02/01 03:39

前提・実現したいこと

WPFアプリでXAML Islandsによってコントロールをホストして使用しています。
その時、コントロールのイベントをラップしようとしたところ、RoutedEventHandler で宣言されたイベントは
ラップすることができませんでした。

RoutedEventHandler で宣言されたイベントをラップするには、どの様にするのでしょうか?

下記コードは、
https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/blob/master/Microsoft.Toolkit.Wpf.UI.Controls/InkToolbar/InkToolbar.cs
を参考に、イベントをラップしています。すると以下のようなエラーメッセージが発生します。

CS0123 デリゲート 'RoutedEventHandler' に一致する 'OnToggled' のオーバーロードはありません

参考にしたページのイベントハンドラは、TypedEventHandler で宣言されている一方、今回のToggled は RoutedEventHandler で宣言されていることは理解しましたが、RoutedEventHandler で宣言しているイベントをラップするには、どの様にするのでしょうか?

該当のソースコード

C#

1using System; 2using System.Windows; 3using UWP = Windows.UI.Xaml.Controls; 4 5namespace WrapControls 6{ 7 /// <summary> 8 /// Wpf-enabled wrapper for <see cref="windows.UI.Xaml.Controls.ToggleSwitch"/> 9 /// </summary> 10 public class UwpToggleSwitch : Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHostBase 11 { 12 internal UWP.ToggleSwitch UwpControl => ChildInternal as UWP.ToggleSwitch; 13 14 protected override void OnInitialized(EventArgs e) 15 { 16 // Bind dependency properties across controls 17 // properties of FrameworkElement 18 Bind(nameof(Style), StyleProperty, UWP.ToggleSwitch.StyleProperty); 19 Bind(nameof(MaxHeight), MaxHeightProperty, UWP.ToggleSwitch.MaxHeightProperty); 20 Bind(nameof(FlowDirection), FlowDirectionProperty, UWP.ToggleSwitch.FlowDirectionProperty); 21 Bind(nameof(Margin), MarginProperty, UWP.ToggleSwitch.MarginProperty); 22 Bind(nameof(HorizontalAlignment), HorizontalAlignmentProperty, UWP.ToggleSwitch.HorizontalAlignmentProperty); 23 Bind(nameof(VerticalAlignment), VerticalAlignmentProperty, UWP.ToggleSwitch.VerticalAlignmentProperty); 24 Bind(nameof(MinHeight), MinHeightProperty, UWP.ToggleSwitch.MinHeightProperty); 25 Bind(nameof(Height), HeightProperty, UWP.ToggleSwitch.HeightProperty); 26 Bind(nameof(MinWidth), MinWidthProperty, UWP.ToggleSwitch.MinWidthProperty); 27 Bind(nameof(MaxWidth), MaxWidthProperty, UWP.ToggleSwitch.MaxWidthProperty); 28 Bind(nameof(UseLayoutRounding), UseLayoutRoundingProperty, UWP.ToggleSwitch.UseLayoutRoundingProperty); 29 Bind(nameof(Name), NameProperty, UWP.ToggleSwitch.NameProperty); 30 Bind(nameof(Tag), TagProperty, UWP.ToggleSwitch.TagProperty); 31 Bind(nameof(DataContext), DataContextProperty, UWP.ToggleSwitch.DataContextProperty); 32 Bind(nameof(Width), WidthProperty, UWP.ToggleSwitch.WidthProperty); 33 34 //ここでエラー 35 UwpControl.Toggled += OnToggled; 36 37 base.OnInitialized(e); 38 } 39 40 public event EventHandler<object> Toggled = (sender, args) => { }; 41 42 private void OnToggled(UWP.ToggleSwitch sender, object args) 43 { 44 Toggled?.Invoke(this, args); 45 } 46 } 47}

参考としたサイト

WPFにおけるコントロールのホストに関する参考ページ(Microsoft Docs)
XAML Islands を使用して WPF アプリで標準 WinRT XAML コントロールをホストする

ホストしたコントロールのラッピングに関する参考ページ
WPF on .NET Core 3.0 で XAML Islands してみよう

イベントハンドラのタッピング参考ページ
https://github.com/windows-toolkit/Microsoft.Toolkit.Win32/blob/master/Microsoft.Toolkit.Wpf.UI.Controls/InkToolbar/InkToolbar.cs

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

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

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

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

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

TN8001

2021/01/29 21:27

delegateの定義からはこうなります。 OnToggled(object sender, Windows.UI.Xaml.RoutedEventArgs args) UwpControl.Toggledの後に+=と打ってタブキーを押すと、イベントハンドラの自動生成ができます。 しかし手元でいろいろ試してはいるのですが、DependencyPropertyの相互バインドが全く動いてない気がします(InkToolbar等でも) これ→ Bind(nameof(Style), 。。。 いくつかのプロパティは出力にエラーが出ているし、エラーがないのも変更が反映されません。 docsにそって忠実にセットアップしたつもりなのですが。。。 これができないのではラップの意味なしですし、解決法もわかってないのでこちらに書きました^^; そちらでは動いていますか?
MomenToufu

2021/02/01 03:46 編集

TN8001 さん RoutedEventHandler にハンドルを追加することができました。ありがとうございます。 TN8001さんの求めている回答になるかわかりませんが、今回の作業に関して参考としたページを質問本文の「参考としたサイト」に記載しました。ご参考ください。 その他、何か回答できることがあれば回答いたします。
TN8001

2021/02/01 04:11

提示urlは全て確認済みですが、現象が通じていない気もするので説明させてください。 ToggleSwitchをラップするために、例えばDependencyProperty IsOnPropertyを作ります。 でBind(nameof(IsOn), IsOnProperty, UWP.ToggleSwitch.IsOnProperty); とすると。。 でxamlでこうした場合 <local:UwpToggleSwitch IsOn="{Binding IsChecked, ElementName=checkBox}" /> <CheckBox x:Name="checkBox" /> 連動しなければおかしいのですがなぜか連動しません(CheckBox側からバインドしても同様) MomenToufuさんのほうで問題がないのであれば、気にしないで結構です(特に今使う予定もないので^^;
MomenToufu

2021/02/01 04:33

理解しました。次のような解釈で良いですか? 1.TN8001さんの言うように、ToggleSwitch と CheckBox を配置してデバッグ 2.CheckBox にチェックを入れる。 3.ToggleSwitch が切り替わる。 (本来ならバインドしているから、ToggleSwitch が切り替わる。) 動かないですね(汗 すると、コントロールを画面上に配置できるだけになっているということですね。
TN8001

2021/02/01 04:50

あぁそうですか。。。 それではWindowsXamlHostで置いても大差なくなってしまいますよね;; しかし前にやったときは動いていたような気もするんですよね(気のせいかもしれませんが^^; 最近WinUI3(Project Reunion)の動きも活発ですし、Xaml Islandsも一時的な不具合?なのかもしれません。 個人的にはWinUI3早く出ないかな~って感じです^^;
MomenToufu

2021/02/02 08:18

WinUI3だと XAML IsLands が必要なくなるんですかね。そうであれば、あまり深追いしない方がいいかもしれないですね。
guest

回答1

0

自己解決

TN8001さんご指摘の通り、該当のコードを次のようにすることで解消した。

C#

1using System; 2using System.Windows; 3using UWP = Windows.UI.Xaml.Controls; 4 5 6namespace WrapControls 7{ 8 /// <summary> 9 /// Wpf-enabled wrapper for <see cref="windows.UI.Xaml.Controls.ToggleSwitch"/> 10 /// </summary> 11 public class UwpToggleSwitch : Microsoft.Toolkit.Wpf.UI.XamlHost.WindowsXamlHostBase 12 { 13 internal UWP.ToggleSwitch UwpControl => ChildInternal as UWP.ToggleSwitch; 14 15 public string IsOn 16 { 17 get { return (string)GetValue(IsOnProperty); } 18 set { SetValue(IsOnProperty, value); } 19 } 20 public static readonly DependencyProperty IsOnProperty = 21 DependencyProperty.Register("IsOn", typeof(string), typeof(UwpToggleSwitch), new PropertyMetadata(null)); 22 23 public UwpToggleSwitch() : base(typeof(UWP.ToggleSwitch).FullName) 24 { 25 } 26 27 protected override void OnInitialized(EventArgs e) 28 { 29 // Bind dependency properties across controls 30 // properties of FrameworkElement 31 Bind(nameof(Style), StyleProperty, UWP.ToggleSwitch.StyleProperty); 32 Bind(nameof(MaxHeight), MaxHeightProperty, UWP.ToggleSwitch.MaxHeightProperty); 33 Bind(nameof(FlowDirection), FlowDirectionProperty, UWP.ToggleSwitch.FlowDirectionProperty); 34 Bind(nameof(Margin), MarginProperty, UWP.ToggleSwitch.MarginProperty); 35 Bind(nameof(HorizontalAlignment), HorizontalAlignmentProperty, UWP.ToggleSwitch.HorizontalAlignmentProperty); 36 Bind(nameof(VerticalAlignment), VerticalAlignmentProperty, UWP.ToggleSwitch.VerticalAlignmentProperty); 37 Bind(nameof(MinHeight), MinHeightProperty, UWP.ToggleSwitch.MinHeightProperty); 38 Bind(nameof(Height), HeightProperty, UWP.ToggleSwitch.HeightProperty); 39 Bind(nameof(MinWidth), MinWidthProperty, UWP.ToggleSwitch.MinWidthProperty); 40 Bind(nameof(MaxWidth), MaxWidthProperty, UWP.ToggleSwitch.MaxWidthProperty); 41 Bind(nameof(UseLayoutRounding), UseLayoutRoundingProperty, UWP.ToggleSwitch.UseLayoutRoundingProperty); 42 Bind(nameof(Name), NameProperty, UWP.ToggleSwitch.NameProperty); 43 Bind(nameof(Tag), TagProperty, UWP.ToggleSwitch.TagProperty); 44 Bind(nameof(DataContext), DataContextProperty, UWP.ToggleSwitch.DataContextProperty); 45 Bind(nameof(Width), WidthProperty, UWP.ToggleSwitch.WidthProperty); 46 47 Bind(nameof(IsOn), IsOnProperty, UWP.ToggleSwitch.IsOnProperty); 48 49 UwpControl.Toggled += OnToggled; 50 51 base.OnInitialized(e); 52 } 53 54 // 変更前① 55 //public event EventHandler<object> Toggled = (sender, args) => { }; 56 // 57 58 // 変更後① 59 public event Windows.UI.Xaml.RoutedEventHandler Toggled = (sender, e) => { }; 60 61 // 変更前② 62 //private void OnToggled(UWP.ToggleSwitch sender, object args) 63 //{ 64 // Toggled?.Invoke(this, args); 65 //} 66 // 67 68 // 変更後② 69 private void OnToggled(object sender, Windows.UI.Xaml.RoutedEventArgs e) 70 { 71 Toggled?.Invoke(this, e); 72 } 73 74 75 } 76 77} 78

投稿2021/02/01 03:53

MomenToufu

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問