On a button's click event, execute event handl

2020-05-06 17:36发布

问题:

On a button's click, i want it to execute an event handler method that is another class apart from the window class.

I believe creating a ObjectDataProvider object which is binded to the event handler method in the other class, then binding said object to the Click event would do the trick, but it didn't.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using System.Data.SqlClient;

namespace LoginNS
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class LoginWindow : Window
{

    public LoginWindow()
    {
        InitializeComponent();

    }

}

public class SQLServerClass
{
    public void ConnectSQLServer(object sender, RoutedEventArgs e)
    {
        try
        {
            SqlConnection conn = new SqlConnection("Data Source=tcp:172.16.1.71;Initial Catalog=Sample;User ID=sa;Password=hbkrko");
            conn.Open();
            MessageBox.Show("success");
        }
        catch
        {
            MessageBox.Show("db error");
        }
    }
}

}

Here is the resource and how i'm using it which is incorrect because i get an error message:

<ObjectDataProvider x:Key="loginFunction" ObjectType="{x:Type local:SQLServerClass}" MethodName="ConnectSQLServer"/>

<Grid DataContext="{Binding Path=LoginNS}" Width="400" Height="200">
    <Button x:Name="LoginButton" Style="{StaticResource LoginButton}" Click="{Binding Source={StaticResource loginFunction}}"/>
</Grid>

Immediate run-time error:

Additional information: 'Provide value on 'System.Windows.Data.Binding' threw an exception.' Line number '24' and line position '75'.

回答1:

ObjectDataProvider is used to create object instances that can be used as binding source. In your case ConnectSQLServer method does not return any object that can be used for binding.

The best option for your scenario is to use RelayCommand. You can read about how to achieve this at http://www.codeproject.com/Articles/126249/MVVM-Pattern-in-WPF-A-Simple-Tutorial-for-Absolute

In your case, with RelayCommand your SQLServerClass will be something like this

public class SQLServerClass
{
    public SQLServerClass()
    {
        LoginCommand = new RelayCommand<object>(LoginCommandExecute, LoginCommandCanExecute);
    }
    public void ConnectSQLServer(object sender, RoutedEventArgs e)
    {
        try
        {
            SqlConnection conn = new SqlConnection("Data Source=tcp:172.16.1.71;Initial Catalog=Sample;User ID=sa;Password=hbkrko");
            conn.Open();
            MessageBox.Show("success");
        }
        catch
        {
            MessageBox.Show("db error");
        }
    }

    public ICommand LoginCommand { get; set; }

    private void LoginCommandExecute(object arg)
    {
        ConnectSQLServer(this, new RoutedEventArgs());
    }

    private bool LoginCommandCanExecute(object arg)
    {
        return true;
    }
}

And your XAML

<Window.Resources>
    <ObjectDataProvider x:Key="loginFunction" ObjectType="{x:Type local:SQLServerClass}"/>
</Window.Resources>
<Grid>


    <Grid  Width="400" Height="200">
        <Button x:Name="LoginButton"  Command="{Binding Path=LoginCommand, Source={StaticResource loginFunction}}"/>
    </Grid>
</Grid>

Note that you can use the MvvmLight library. It already contains an implementation of the RelayCommand class and other useful classes for WPF MVVM application.



回答2:

Why can't you use this:

InitializeComponent();
sqlServerInstance = new SQLServerClass();
LoginButton.Click += MainConnectSQLServer()

And

private void MainConnectSQLServer(object sender, RoutedEventArgs e)
{
    sqlServerInstance.ConnectSQLServer(sender, e);
}


标签: c# .net wpf button