C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: C#のDLLをVBから呼ぶとWithEventsがない


(過去ログ 178 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■102311 / inTopicNo.1)  C#のDLLをVBから呼ぶとWithEventsがない
  
□投稿者/ ded (1回)-(2023/08/22(Tue) 14:03:20)

分類:[.NET 全般] 

VS2022 Pro 17.7.1
Framework 4.7.2
DLL:C#
EXE:VB
※同一ソリューションでプロジェクト参照です。

VBからC#で作ったフォームの継承を行うと
「BC30506(Handles 句には、それを含む型または基本型の 1 つで定義された WithEvents 変数が必要です。)」
が発生する。
エラーの内容は理解はできるのですが、解決方法がわかりません。
※C#でイベントを全部定義して、VBでoverrideすればよいのでしょうが、モヤモヤするし全イベントは大変

よろしくお願いします。

----Form1.cs(dll)
using System.Windows.Forms;

namespace ClassLibrary1
{
    public partial class Form1 : Form
    {
        // Form1.Designer.cs
        // private to protected
        protected System.Windows.Forms.Button button1;

        public Form1()
        {
            InitializeComponent();

            
        }
    }
}

----Form2.vb(exe)
Imports ClassLibrary1

Public Class Form2
    Inherits Form1
    Private Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click ←BC30506

    End Sub
End Class

引用返信 編集キー/
■102312 / inTopicNo.2)  Re[1]: C#のDLLをVBから呼ぶとWithEventsがない
□投稿者/ Hongliang (1291回)-(2023/08/22(Tue) 14:36:09)
C#で定義したフィールドをVBでHandlesするのは無理ですね。
AddHandlerステートメントで明示的にイベントとイベントハンドラを関連付けるのはどうでしょうか。

引用返信 編集キー/
■102313 / inTopicNo.3)  Re[1]: C#のDLLをVBから呼ぶとWithEventsがない
□投稿者/ 魔界の仮面弁士 (3685回)-(2023/08/22(Tue) 15:31:05)
No102311 (ded さん) に返信
> ※C#でイベントを全部定義して、VBでoverrideすればよいのでしょうが、モヤモヤするし全イベントは大変


案1)

Imports ClassLibrary1
Public Class Form2
 Inherits Form1
 Protected Overrides Sub OnLoad(e As EventArgs)
  MyBase.OnLoad(e)
  AddHandler Button1.Click, AddressOf button1_Click
 End Sub
 Private Sub button1_Click(sender As Object, e As EventArgs)

 End Sub
End Class



案2)

namespace ClassLibrary1
{
  [DefaultEvent(nameof(ButtonClick))]
  public partial class Form1 : Form
  {
    public event EventHandler ButtonClick;
    public Form1()
    {
      InitializeComponent();
      foreach (Button button in new[]{ button1, button2, button3})
      {
        button.Click += delegate { ButtonClick?.Invoke(button, EventArgs.Empty); };
      }
    }
  }
}


Imports ClassLibrary1
Public Class Form2
  Inherits Form1
  Private Sub Form2_ButtonClick(sender As Button, e As EventArgs) Handles MyBase.ButtonClick
    MsgBox(sender.Name)
  End Sub
End Class

引用返信 編集キー/
■102314 / inTopicNo.4)  Re[2]: C#のDLLをVBから呼ぶとWithEventsがない
□投稿者/ ded (2回)-(2023/08/22(Tue) 17:10:42)
No102312 (Hongliang さん) に返信
■No102313 (魔界の仮面弁士 さん) に返信

解答ありがとうございます。

お二方のAddHandlerにします。
ありがとうございました。

----Form1.cs(dll)

using System.ComponentModel;
using System.Windows.Forms;

namespace ClassLibrary1
{
    [DefaultEvent(nameof(ButtonClick))]
    //[DefaultEvent(nameof(CheckboxCheckedChanged))]  // CS50579
    //[DefaultEvent(nameof(ButtonClick), nameof(CheckboxCheckedChanged))] // CS1729
    public partial class Form1 : Form
    {
        // Form1.Designer.cs
        // private to protected
        protected System.Windows.Forms.Button button1;

        public event EventHandler ButtonClick;

        // Checkboxを追加したら? => CS50579/CS1729でダメ(Defaultじゃなくなるか...)
        //public event EventHandler CheckboxCheckedChanged;   

        public Form1()
        {
            InitializeComponent();
            // 案2=魔界の仮面弁士さん
            //foreach (var b in new[] { button1, button2, button3 })
            //{
            //    b.Click += delegate { ButtonClick?.Invoke(b, EventArgs.Empty); };
            //};
            //foreach( var c in new[] { checkBox1, checkBox2})
            //{
            //    c.Click += delegate { CheckboxCheckedChanged?.Invoke(c, EventArgs.Empty); };
            //}
            // ↓Button, CheckBoxをDefaultEventデリゲートに...
            //foreach (var c in new Control[] { button1, button2, button3, checkBox1, checkBox2 })
            //{
            //    c.Click += delegate { ButtonClick?.Invoke(c, EventArgs.Empty); };
            //};
        }

        private  void button1_Click(object sender, EventArgs e)
        {
            this.Text = ((Control)sender).Name;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.Text = ((Control)sender).Name;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.Text = ((Control)sender).Name;
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            var c = (CheckBox)sender;
            this.Text = $"{c.Name}:{c.Checked}";
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            var c = (CheckBox)sender;
            this.Text = $"{c.Name}:{c.Checked}";
        }

    }
}


----Form2.vb(exe)
Imports ClassLibrary1

Public Class Form2
    Inherits Form1

    ' 案1=Hongliangさん/魔界の仮面弁士さん
    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' 必要なイベントだけAddHandler
        AddHandler button1.Click, AddressOf button1_Click
        AddHandler button2.Click, AddressOf button2_Click
        'AddHandler button3.Click, AddressOf button3_Click
        AddHandler checkBox1.CheckedChanged, AddressOf checkBox1_CheckedChanged
        AddHandler checkBox2.CheckedChanged, AddressOf checkBox2_CheckedChanged

    End Sub

    ' 案2
    Private Sub button_Click(sender As Object, e As EventArgs) Handles MyBase.ButtonClick
        'Select Case sender.Name
        '    Case button1.Name : button1_Click(sender, e)
        '    Case button2.Name : button2_Click(sender, e)
        '    Case button3.Name : button3_Click(sender, e)
        '    Case checkBox1.Name : checkBox1_CheckedChanged(sender, e)
        '    Case checkBox2.Name : checkBox2_CheckedChanged(sender, e)
        'End Select
    End Sub

    Private Sub button1_Click(sender As Object, e As EventArgs)
        MessageBox.Show(DirectCast(sender, Control).Name)
    End Sub

    Private Sub button2_Click(sender As Object, e As EventArgs)
        MessageBox.Show(DirectCast(sender, Control).Name)
    End Sub

    Private Sub button3_Click(sender As Object, e As EventArgs)
        MessageBox.Show(DirectCast(sender, Control).Name)
    End Sub

    Private Sub checkBox1_CheckedChanged(sender As Object, e As EventArgs)
        Dim c As CheckBox = DirectCast(sender, CheckBox)
        MessageBox.Show($"{c.Name}:{c.Checked}")
    End Sub

    Private Sub checkBox2_CheckedChanged(sender As Object, e As EventArgs)
        Dim c As CheckBox = DirectCast(sender, CheckBox)
        MessageBox.Show($"{c.Name}:{c.Checked}")
    End Sub

End Class

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -