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

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

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

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

WPF

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

Q&A

解決済

1回答

1713閲覧

WinForm で行っている WebBrowser 上にLabel(TextBlock)を配置や線を引く処理を WPF に書き換えたい

byori

総合スコア71

C#

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

WPF

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

1グッド

0クリップ

投稿2020/09/07 07:24

WinForm で行っている WebBrowser 上にLabel(TextBlock)を配置や線を引くことを WPF に書き換えたいのですがどのようにしたらできますか?

コードは長いです。ベースとなる Form に Opacity = 0.01 まで薄くした Form と透明Form に描画させることでできています。Opacity のForm にまうすでなぞるともう一つのFormに描画されます。
WPF側では、なぞって書くのではなく保存されたデータから描画だけします。
Label(TextBlock)は、WebBrowser 上に置かれたように重なって表示します。
線は、WebBrowser 上にの任意の位置に線が引かれるようになります。

ここで教えていただいた内容です。「https://teratail.com/questions/285584」
別アプリにも追加したい機能ですが、すでにWPFで大半できています。

下記のコードは、長いです。コントロールの作方法と描画についてアドバイスいただければありがたいです。

C#

1public partial class RequestformDisplayForm : Form 2{ 3 public RequestformDisplayForm() 4 { 5 InitializeComponent(); 6 7 8 // WebBrowser に線を描画するための画面作製 9 m_frmdummy = new Form(); 10 11 // ダミーのフォーム内でクリックすると線の描画を開始できる 12 // 画像描画用のフォーム内でのクリックでは線を描画できない 13 m_parent = this; // parent; 14 m_frmdummy.TransparencyKey = Color.Transparent; 15 m_frmdummy.Owner = m_parent; 16 m_frmdummy.Text = "これはダミー"; 17 m_frmdummy.Opacity = 0.01; // Opacity = 0では上手くいかなかった。 18 m_frmdummy.Width = this.ClientSize.Width - (int)((float)ClientSize.Width * 0.06); 19 m_frmdummy.Height = this.ClientSize.Height - (int)((float)ClientSize.Height * 0.1);//- 5% ほど引いて「履歴_1」をクリックできるようにする; 20 m_frmdummy.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; 21 22 m_frm.Owner = m_parent; 23 m_frm.TransparencyKey = SystemColors.Control; 24 m_frm.Text = "画像描画用Form"; 25 m_frm.Width = this.ClientSize.Width; 26 m_frm.Height = this.ClientSize.Height; 27 m_frm.FormBorderStyle = FormBorderStyle.None; 28 29 30 label_TXT1 = new Label(); 31 label_TXT1.Size = new Size(176, 80); 32 label_TXT1.Location = new Point(100, 100); 33 label_TXT1.BackColor = Color.Yellow; 34 m_frm.Controls.Add(label_TXT1); 35 } 36 37 private Form m_frm = new Form(); 38 private Form _m_frmdummy; 39 40 private Form m_frmdummy 41 { 42 [MethodImpl(MethodImplOptions.Synchronized)] 43 get 44 { 45 return _m_frmdummy; 46 } 47 48 [MethodImpl(MethodImplOptions.Synchronized)] 49 set 50 { 51 if (_m_frmdummy != null) 52 { 53 _m_frmdummy.MouseMove -= m_frmdummy_MouseMove; 54 } 55 56 _m_frmdummy = value; 57 if (_m_frmdummy != null) 58 { 59 _m_frmdummy.MouseMove += m_frmdummy_MouseMove; 60 } 61 } 62 } 63 private void m_frmdummy_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 64 { 65 66 } 67 68 private Form _m_parent; 69 private Form m_parent 70 { 71 [MethodImpl(MethodImplOptions.Synchronized)] 72 get 73 { 74 return _m_parent; 75 } 76 77 [MethodImpl(MethodImplOptions.Synchronized)] 78 set 79 { 80 if (_m_parent != null) 81 { 82 _m_parent.LocationChanged -= m_parent_LocationChanged; 83 } 84 85 _m_parent = value; 86 if (_m_parent != null) 87 { 88 _m_parent.LocationChanged += m_parent_LocationChanged; 89 } 90 } 91 } 92 93 /// <summary> 94 /// ラベルも移動できるようにする 95 /// </summary> 96 private Label _label_TXT1; 97 private Label label_TXT1 98 { 99 [MethodImpl(MethodImplOptions.Synchronized)] 100 get 101 { 102 return _label_TXT1; 103 } 104 105 [MethodImpl(MethodImplOptions.Synchronized)] 106 set 107 { 108 if (_label_TXT1 != null) 109 { 110 _label_TXT1.MouseMove -= _label_TXT1_MouseMove; 111 _label_TXT1.MouseDown -= _label_TXT1_MouseDown; 112 } 113 114 _label_TXT1 = value; 115 if (_label_TXT1 != null) 116 { 117 _label_TXT1.MouseMove += _label_TXT1_MouseMove; 118 _label_TXT1.MouseDown+= _label_TXT1_MouseDown; 119 } 120 } 121 } 122 123 private void _label_TXT1_MouseDown(object sender, MouseEventArgs e) 124 { 125 ClickStart = e.Location; 126 } 127 private void _label_TXT1_MouseMove(object sender, MouseEventArgs e) 128 { 129 if ((e.Button == MouseButtons.Left)) 130 { 131 Point mpMoveLocaion = new Point(e.X - ClickStart.X + ((Label)sender).Location.X, e.Y - ClickStart.Y + ((Label)sender).Location.Y); 132 ((Label)sender).Location = mpMoveLocaion; // ラベルの移動 133 } 134 } 135 136 137 // このメソッドを外部から呼び出す 138 public void ShowForm() 139 { 140 m_frmdummy.Show(); 141 m_frm.Show(); 142 143 int marginX = this.Width - this.ClientSize.Width; 144 int marginY = this.Height - this.ClientSize.Height + (int)((float)ClientSize.Height * 0.05); 145 Point posi = new Point(this.Location.X + (marginX / 2), this.Location.Y + marginY); 146 m_frm.Location = posi; //m_parent.PointToScreen(this.Location); 147 m_frmdummy.Location = posi;//m_parent.PointToScreen(this.Location); 148 } 149 150 protected override void OnLocationChanged(EventArgs e) 151 { 152 m_parent_LocationChanged(null, null); 153 base.OnLocationChanged(e); 154 } 155 156 protected override void OnSizeChanged(EventArgs e) 157 { 158 m_frm.Size = this.Size; 159 if (m_frmdummy != null) 160 { 161 int width = this.ClientSize.Width - (int)((float)ClientSize.Width * 0.06); 162 //int height = this.ClientSize.Height - (int)((float)ClientSize.Height * 0.1);//- 5% ほど引いて「履歴_1」をクリックできるようにする; 163 int height = this.Bottom - this.Top - 120;//- 5% ほど引いて「履歴_1」をクリックできるようにする; 164 m_frmdummy.Size = new Size(width, height); 165 // m_frmdummy.Size = this.Size; 166 167 168 // 一度線を消して引き直す 169 Brush brs = new SolidBrush(SystemColors.Control); 170 Rectangle rect = new Rectangle(m_frm.PointToClient(m_frm.Location), m_frm.Size); 171 Graphics g = m_frm.CreateGraphics(); 172 g.FillRectangle(brs, rect); 173 g.Dispose(); 174 175 DrawLine(alloc); 176 } 177 178 base.OnSizeChanged(e); 179 } 180 181 private void m_parent_LocationChanged(object sender, EventArgs e) 182 { 183 if (m_parent != null && m_frm != null) 184 { 185 // m_frm.Location = m_parent.PointToScreen(this.Location); 186 int marginX = this.Width - this.ClientSize.Width; 187 int marginY = this.Height - this.ClientSize.Height + (int)((float)ClientSize.Height * 0.05); 188 Point posi = new Point(this.Location.X + (marginX / 2), this.Location.Y + marginY); 189 m_frm.Location = posi; //m_parent.PointToScreen(this.Location); 190 } 191 if (m_frmdummy != null && m_parent != null) 192 { 193 //m_frmdummy.Location = m_parent.PointToScreen(this.Location); 194 int marginX = this.Width - this.ClientSize.Width; 195 int marginY = this.Height - this.ClientSize.Height + (int)((float)ClientSize.Height * 0.05); 196 Point posi = new Point(this.Location.X + (marginX / 2), this.Location.Y + marginY); 197 m_frmdummy.Location = posi; 198 } 199 } 200 // ////////////////////////////////////////////////////////////////////////////////////////////////////// 201
TN8001👍を押しています

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

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

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

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

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

TN8001

2020/09/07 08:44

空域の問題は目途が付いていて、描画法が問題ってことですか? 手軽にやるならCanvasに、TextBlockやLineを置いてく感じでしょうか。
byori

2020/09/07 13:07

ありがとうございます。 Canvas に WebBrowser を配置しその上に textBlock や Line を引くことは可能でしょうか? ブラウザに表示する html データ上に TextBlock や 栓を引きたいのです。
guest

回答1

0

ベストアンサー

空域問題(Airspace problem)

WPFもフォームと同じでWebBrowserの上には重ねられません。
Chromiumだったらだいじょぶだったと思いますが、WebBrowserを使うなら同じようにウィンドウを重ねることになると思います。

まだ何も手を付けていなければ、↓なんかはそのまま使えるかもしれません。
michaelsutton/hwnd-adorner: WPF library supporting layers (adornments) over any hwnd hosted by an HwndHost

ざっと試したところ動きました(ちょっとリサイズが重い気がするが、最悪参考にはなると思います)

描画方法

CanvasではTopLeftで座標指定ができるので、フォームと似た感覚で使えると思います。


追記
デモプロジェクトから下記2ファイルのみ変更

xml

1<UserControl 2 x:Class="Demo.BrowserAdornment" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 5 <Canvas> 6 <Label 7 x:Name="label" 8 Canvas.Left="0" 9 FontSize="50" 10 Foreground="DarkRed"> 11 Browser Adornment (; 12 </Label> 13 <Button Click="Button_Click" Content="aaa" /> 14 </Canvas> 15</UserControl>

cs

1using System.Windows; 2using System.Windows.Controls; 3 4namespace Demo 5{ 6 public partial class BrowserAdornment : UserControl 7 { 8 public BrowserAdornment() => InitializeComponent(); 9 10 private void Button_Click(object sender, RoutedEventArgs e) 11 { 12 Canvas.SetLeft(label, Canvas.GetLeft(label) + 10); 13 label.Content = $"Canvas.Left{Canvas.GetLeft(label)}"; 14 } 15 } 16}

投稿2020/09/07 13:26

編集2023/07/23 05:25
TN8001

総合スコア9242

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

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

byori

2020/09/08 02:51

お世話になります。 ご紹介頂いたサンプル面白そうです。 BrowserAdornmentのスクロールバーとMainWindowのスクロールバーをリンクして移動させるにはどうする?という疑問がでてきましたが、このサンプルもう少し検討してさせてください。
byori

2020/09/09 01:48

お世話になります。 サンプルを参考に線やラベルをブラウザ上に表示させるようできそうです。 ただ、表示のタイミングが下記のURLはコンストラクタのみ、線やラベルはウインドウ作成時のみのようです。ウインドウが出来てから表示や表示内容の変更をかけても変更されません。 毎回、作製・破棄で対応しようと思います。 でも、何度か動かすと処理が重くなってくるのが気になります。 私では重くなる理由を調べる技量はありません。 これで対応していきたいと思います。ありがとうございました。 public class BrowserPresenter : HwndHostPresenter { public BrowserPresenter() { var browser = new WebBrowser(); browser.Source = new Uri(adress); HwndHost = browser; RegisterToAppShutdown(); } class BrowserAdornment : UserControl private void UserControl_Loaded(object sender, RoutedEventArgs e) { ShowData(); // 線やラベルを表示 }
TN8001

2020/09/09 03:45

> ウインドウが出来てから表示や表示内容の変更をかけても変更されません。 そんなことはないですけど?検証コードを追記しました。 > 私では重くなる理由を調べる技量はありません。 同じく^^;
byori

2020/09/09 05:43

お世話になります。 > そんなことはないですけど?検証コードを追記しました。 あれ?、その通りでしたね。 何か、勘違いがあったみたいです。 追加情報までありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問