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

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

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

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

Q&A

解決済

2回答

1653閲覧

ユーザーコントロールの色をグラデーションしたいです。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2022/09/20 12:10

編集2022/09/21 19:15

前提・ 実現したいこと

Formやユーザコントロールなどの背景色をグラデーションに色が塗る方法が知りたいです。

visual stadio2022を使ってc#でプログラミングしています。
ショッピングサイトのようなシステムを作っています。
それを実装のとき、Windowサイズをマウスで大きさが変更するとき、
Form内のパネルに追加したユーザーコントロールのSizeの大きさも変わります。

VisualStudioでwindows formのForm上には
Panel1(左上)、Panel2(右上)、Panel3(左下)、Panel4(右下)で構成されています。

また、Panel3(左下)にはUserControl1からUserControl2へと画面遷移するために必要なユーザーコントロールが複数あります。

知りたいことはユーザコントロール内にPanelなどのコントロールの追加による表示ではなく、
サンプル写真のように赤丸のように直接、Formやユーザコントロールなどの背景色をグラデーションに色が塗る方法が知りたいです。

できれば解答する際にコードの解説やコメントがあるとわかりやすいのでお願いします。

イメージ説明

発生している問題・エラーメッセージ

https://dobon.net/vb/dotnet/graphics/lineargradientbrush.html
https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/784gradbutton/gradbutton.html
を参考にしたが、
ユーザコントロール内にPanelやpictureboxなどのコントロールを追加による表示の仕方はユーザコントロールに色が塗られていない部分があるやサンプルのように配置されているボタンが消えてしまうと指摘を受けて
ユーザコントロール内の背景色をグラデーションに変えることがわからない。

該当のソースコード

c#

1//描画先とするImageオブジェクトを作成する 2Bitmap canvas = new Bitmap(PictureBox1.Width, PictureBox1.Height); 3//ImageオブジェクトのGraphicsオブジェクトを作成する 4Graphics g = Graphics.FromImage(canvas); 5 6//縦に白から黒へのグラデーションのブラシを作成 7//g.VisibleClipBoundsは表示クリッピング領域に外接する四角形 8LinearGradientBrush gb = new LinearGradientBrush( 9 g.VisibleClipBounds, 10 Color.White, 11 Color.Black, 12 LinearGradientMode.Vertical); 13 14//四角を描く 15g.FillRectangle(gb, g.VisibleClipBounds); 16 17//リソースを解放する 18gb.Dispose(); 19g.Dispose(); 20 21//PictureBox1に表示する 22PictureBox1.Image = canvas;

試したこと

ユーザーコントロールのイベントpaintを使ったがグラデーションにならないです。

c#

1using System; 2using System.Collections.Generic; 3using System.ComponentModel; 4using System.Data; 5using System.Drawing; 6using System.Linq; 7using System.Text; 8using System.Threading.Tasks; 9using System.Windows.Forms; 10using System.Drawing.Drawing2D; 11 12namespace tram 13{ 14 public partial class UserControl1 : UserControl 15 { 16 public Menu() 17 { 18 InitializeComponent(); 19 20 } 21  private void UserControl1_Paint(object sender, PaintEventArgs e) 22 { 23 Form1 form = (Form1)this.FindForm(); 24 // ビットマップとGraphicsオブジェクトの作成 25 Bitmap bmp = new Bitmap(form.panel3.Width, form.panel3.Height); 26 Graphics g = Graphics.FromImage(bmp); 27 28 // グラデーション・ブラシの作成 29 LinearGradientBrush gradBrush = new LinearGradientBrush( 30 g.VisibleClipBounds, // ビットマップの領域サイズ 31 Color.Navy, // 開始色 32 Color.Purple, // 終了色 33 LinearGradientMode.Vertical); // 縦方向にグラデーション 34 35 // ビットマップをグラデーション・ブラシで塗る 36 e.Graphics.FillRectangle(gradBrush, g.VisibleClipBounds); 37 38 gradBrush.Dispose(); 39 g.Dispose(); 40 41 } 42}

補足情報(FW/ツールのバージョンなど)

Form1のソースコードはこのようになっています。

c#

1public partial class Form1 : Form 2 { 3 4 //ユーザーコントロール1 5 public userControl1 page = new UserControl1(); 6 //ユーザーコントロール2 7 public userControl2 page = new UserControl2(); 8 9 public Form1() 10 { 11 InitializeComponent(); 12 13 //ユーザーコントロールの画面を追加 14 panel3.Controls.Add(userControl1); 15 panel3.Controls.Add(userControl2); 16 17   userControl1.Visible = false; 18 userControl2.Visible = true; 19 20 } 21 22 } 23

また、これは個人的に気になったことであるが、 gradBrush.Dispose();など
Dispose()がなくても画面に図形が挿入されているが
Dispose()があるとないでどのように変わりますか?
自分で調べてもリソース?というものがあるかないか書かれてもの多いです。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/09/20 12:59 編集

まだ言語の理解などによって解決していないです。
Zuishin

2022/09/20 13:26

前のが解決してないのに進めちゃだめでしょう。
退会済みユーザー

退会済みユーザー

2022/09/20 13:37 編集

また質問にも書きましたが前回の場合はパネルが配置されていることがダメであると指摘を受けてしまい、再度質問しました。
Zuishin

2022/09/20 14:05

なぜ課題を他人にやらせてるのか知らないけど、同じ方法でできるので、前の回答を参考にすればできます。 理解せず先に進んでいるからできないだけです。
guest

回答2

0

ベストアンサー

BackgroundImageで画像を貼るのはどうですか?
それならC#コードを一切書かずに実現できます。

BackgroundImageLayoutStretchにしてください。
引き伸ばすので画像の幅は狭くても問題ありませんが、高さはある程度ないと汚くなります。

Control.BackgroundImage プロパティ (System.Windows.Forms) | Microsoft Learn

Control.BackgroundImageLayout プロパティ (System.Windows.Forms) | Microsoft Learn

c# 画像 リソース - Google 検索

グラデーション画像作成 - Google 検索

投稿2022/09/21 10:15

TN8001

総合スコア9198

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

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

0

Dispose について

メモリが足りなくなれば、GC(ガベージコレクタ)が回収しますが、ブラシなどの GDI/GDI++ オブジェクトを放置しておくと、GCがオブジェクトを回収する前に GDI/GDI++ のリソース制限に引っかかり、描画がされなくなることも考えられます。
サンプルプログラムのような小さいプログラムでは問題にならなくても、大規模なプログラムになってくると問題が発生することもあるので、必ず Dispose を実行するようにしてください。
いちばん簡単なのは using ステートメントを使うことですね。

本題

UserControl は、自身にプロパティやメソッドを実装して外部から動作を変更できます。
背景をグラデーションしたいのであれば、グラデーションに関する情報をプロパティとして実装すると良いでしょう。
この場合、LinearGradientBrush を作成するときの引数のうち、開始色、終了色、グラデーションの方向を指定する LinearGradientMode 列挙体 です。
ここで重要なのは、プロパティの値が変更されたら、背景を再描画する必要がある、ということです。
ウインドウハンドルが作成されていれば、Invalidate メソッドを実行して、再描画します。

C#

1using System.Drawing; 2using System.Drawing.Drawing2D; 3using System.Windows.Forms; 4 5public partial class UserControl1 : UserControl 6{ 7 public UserControl1() { 8 InitializeComponent(); 9 // ちらつき防止 10 SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 11 SetStyle(ControlStyles.AllPaintingInWmPaint, true); 12 } 13 14 protected override void OnPaint(PaintEventArgs e) { 15 base.OnPaint(e); 16 using (var gb = new LinearGradientBrush( 17 ClientRectangle, 18 StartColor, 19 EndColor, 20 LinearGradientMode)) { 21 e.Graphics.FillRectangle(gb, ClientRectangle); 22 } 23 } 24 25 private Color _StartColor = Color.White; 26 27 public Color StartColor { 28 get { 29 return _StartColor; 30 } 31 set { 32 if (StartColor != value) { 33 _StartColor = value; 34 if (IsHandleCreated) { 35 Invalidate(); 36 } 37 } 38 } 39 } 40 41 private Color _EndColor = Color.Black; 42 43 public Color EndColor { 44 get { 45 return _EndColor; 46 } 47 set { 48 if (EndColor != value) { 49 _EndColor = value; 50 if (IsHandleCreated) { 51 Invalidate(); 52 } 53 } 54 } 55 } 56 57 private LinearGradientMode _LinearGradientMode = LinearGradientMode.Vertical; 58 59 public LinearGradientMode LinearGradientMode { 60 get { 61 return _LinearGradientMode; 62 } 63 set { 64 if (LinearGradientMode != value) { 65 _LinearGradientMode = value; 66 if (IsHandleCreated) { 67 Invalidate(); 68 } 69 } 70 } 71 } 72}

上のコードはあくまでもサンプルであり、最低限の実装をしているだけです。

プロパティの実装には、いろいろお作法があるのですが、ちょっと説明しきれませんので

「.NET Framework を使用したカスタム Windows フォーム コントロールの開発」
https://learn.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/developing-custom-windows-forms-controls?view=netframeworkdesktop-4.8

を参照してください。

投稿2022/09/20 17:27

編集2022/09/20 18:44
KOZ6.0

総合スコア2597

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.53%

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

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

質問する

関連した質問