创建自定义的WPF事件。

22

我为数据库连接创建了一个用户控件,用户需要输入用户名和密码进行连接。这个用户控件在MainWindow.xaml中。

现在,在我的用户控件的代码后台中,我创建了一个MSSQL连接。如果成功登录,我想要引发一个自定义事件以在MainWindow中公开。

例如,在MyUserControl.xaml.cs中

try
{

    using (SqlConnection sqlConn = new SqlConnection(connection))
    {
        sqlConn.Open();
        MessageBox.Show("Connessione Riuscita!", "Connessione a " + TextIP.Text, MessageBoxButton.OK, MessageBoxImage.Information);
        RaiseMyEvent();
        sqlConn.Close();                 
    }
}
catch (SqlException ex)
{
    MessageBox.Show("Connessione Fallita: " + ex.Message, "Connessione a " + TextIP.Text, MessageBoxButton.OK, MessageBoxImage.Error);
}

我希望在MainWindow.xaml中使用我个性化的事件:

<Window x:Class="XLogin.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:XLogin" WindowStartupLocation="CenterScreen">
    <Grid>
        <local:DBLogin x:Name="DBLoginFrame" MyPersonalizedUCEvent="DBLoginFrame_MyPersonalizedUCEvent"/>
    </Grid>
</Window>

我需要这个可以支持多种类型连接的功能(如 MSSQL、Oracle、MySQL 等)。

如何获取这个功能?

2个回答

28

首先,您应该定义一个委托,然后使用该委托来定义事件。

在您的MyUserControl.xaml.cs文件中添加以下内容:

选项1

    public delegate void MyPersonalizedUCEventHandler(string sampleParam);

    public event MyPersonalizedUCEventHandler MyPersonalizedUCEvent;

    public void RaiseMyEvent()
    {
        // Your logic
        if (MyPersonalizedUCEvent != null)
        {
            MyPersonalizedUCEvent("sample parameter");
        }
    }

就这样了。你已经定义了你的事件。

选项2

    public event Action<String> MyPersonalizedUCEvent;

    public void RaiseMyEvent()
    {
        // Your logic
        if (MyPersonalizedUCEvent != null)
        {
            MyPersonalizedUCEvent("sample parameter");
        }
    }

关于Action委托的更多信息请参见此链接

注意:

在许多情况下,如果事件没有正确使用,它们可能会导致内存泄漏。只需确保您编写了代码来删除已注册的事件处理程序,如下所示。

        MyPersonalizedUCEvent -= MyPersonalizedUCEventHandler;

6
@davymartu 但是,通常情况下,您会使用预定义的委托类型之一,例如EventHandlerEventHandler<T>,而不是定义自己的委托类型。 - Clemens
我已经定义了一个简单的事件。但是,如果你想让这个事件冒泡到父容器,你应该创建一个路由事件,而iltzortz的回答解释了如何创建它。 - Anand Murali
第一个选项适合我的情况。 - Hamed Rajabi Varamini

16

首先在你的类中创建一个公共事件:

public event EventHandler<MyEventArgs> SomethingChanged;

NB MyEventArgs是将与事件一起传递给订阅者的对象类型。 对于此示例,它可能是这样的:

NB MyEventArgs 是传递给事件订阅者的对象类型。对于本示例,它可以是这样的:

public class MyEventArgs{
    public String Prop1 {get; set;}
}

接下来原封不动地在你的类中触发它:

SomethingChanged?.Invoke(this, new MyEventArgs() { Prop1="test" });

最后处理方式如下:

private void OnSomethingChanged(object sender, MyEventArgs e)
{
    //TODO
}

NB 您需要订阅该事件才能进入 OnSometingChanged 方法, 订阅方式如下 :

myClass.SomethingChanged+=OnSomethingChanged;

myClass 是你定义 SomethingChanged 的类的一个实例时:


我不明白为什么SomethingChanged会变成非空值,而且Visual Studio显示“在退出构造函数时,'SomethingChanged'必须包含非空值。” - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接