捕获派生类中通用按钮的单击事件

本文关键字:按钮 单击 事件 派生 | 更新日期: 2023-09-27 17:58:25

我正在开发一个WPF应用程序,其中大多数控件都是在运行时动态创建的。为了保存一些代码,我创建了各种静态控件。现在,我想创建一个文本框控件,旁边有一个删除按钮。我现在遇到的问题是,如何捕捉控件的事件?(参见代码)

编辑:按照建议,我尝试创建一个自定义控件。但是,我无法使自定义事件正常工作。也就是说,在wpf页面中,我找不到用于挂接处理程序的delete Event。我哪里出错了?到目前为止,我发现当我删除: Grid语句时,会显示Event。

  public class tbTextReadOnlyWithDeleteButton : Grid
{
    public event EventHandler Delete;
    public tbTextReadOnlyWithDeleteButton(int gridrow, int gridcol, string feldname, object quelle, string ctlname, object tag)
    {
        Grid gr = new Grid() { Name = "grMit_" + gridrow + "_" + gridcol + "_" + ctlname };
        gr.SetValue(Grid.RowProperty, gridrow);
        gr.SetValue(Grid.ColumnProperty, gridcol);
        gr.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(30) });
        gr.ColumnDefinitions.Add(new ColumnDefinition());
        gr.Tag = tag;

        Button bu = new Button() { Name = "buLoeschen" };
        bu.SetValue(Grid.ColumnProperty, 0);
        bu.Margin = new Thickness(5, 5, 5, 5);
        bu.Content = "'xE10A";
        bu.FontFamily = new FontFamily("Segoe MDL2 Assets");
        bu.FontSize = 10;
        bu.Tag = quelle;
        bu.Click += Bu_Click;

        TextBox tb = new TextBox();
        tb.SetValue(Grid.RowProperty, 0);
        tb.SetValue(Grid.ColumnProperty, 1);
        tb.IsReadOnly = true;
        tb.VerticalContentAlignment = VerticalAlignment.Center;
        tb.HorizontalContentAlignment = HorizontalAlignment.Left;
        tb.Background = new SolidColorBrush() { Opacity = 1 };
        tb.BorderThickness = new Thickness(0);
        tb.TextWrapping = TextWrapping.Wrap;
        BindingOperations.SetBinding(tb, TextBox.TextProperty, new Binding(feldname) { Source = quelle, Mode = BindingMode.OneWay });
        gr.Children.Add(bu);
        gr.Children.Add(tb);

    }
    private void Bu_Click(object sender, RoutedEventArgs e)
    {
        Delete(sender, e);
    }
}
// in the page it looks like this:
Grid tbMit = new tbTextReadOnlyWithDeleteButton(1, 0, "Name", mit, "name", dat);
tbMit.Delete // <-- Why can't this be found??

结束编辑

    // Control
    public static Grid tbTextReadOnlyWithDeleteButton(int gridrow, int gridcol, string feldname, object quelle)
    {
        Grid gr = new Grid();
        gr.SetValue(Grid.RowProperty, gridrow);
        gr.SetValue(Grid.ColumnProperty, gridcol);
        gr.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(30)});
        gr.ColumnDefinitions.Add(new ColumnDefinition());

        Button bu = new Button() { Name = "buDelete" };
        bu.SetValue(Grid.ColumnProperty, 0);
        bu.Margin = new Thickness(5, 5, 5, 5);
        bu.Content = "'xE10A";
        bu.FontFamily = new FontFamily("Segoe MDL2 Assets");
        bu.FontSize = 10;
        bu.Tag = quelle;

        TextBox tb = new TextBox();
        tb.SetValue(Grid.RowProperty, 0);
        tb.SetValue(Grid.ColumnProperty, 1);
        tb.IsReadOnly = true;
        tb.VerticalContentAlignment = VerticalAlignment.Center;
        tb.HorizontalContentAlignment = HorizontalAlignment.Left;
        tb.Background = new SolidColorBrush() { Opacity = 1 };
        tb.BorderThickness = new Thickness(0);
        tb.TextWrapping = TextWrapping.Wrap;
        BindingOperations.SetBinding(tb, TextBox.TextProperty, new Binding(feldname) { Source = quelle, Mode = BindingMode.OneWay });
        gr.Children.Add(bu);
        gr.Children.Add(tb);
        return gr;
    }
// Usage in Code 
Grid tbMit = glCtlTextbox.tbTextReadOnlyWithDeleteButton(1, 0, "Name", mit);
spStackpanel.Children.Add(tbMit);
//Now I need something like this, which is not working
tbMit.buDelete.Click += buDelete__Click;

有人暗示过如何处理这件事吗?

谢谢!

捕获派生类中通用按钮的单击事件

您有两个解决方案来定义您的用户控件:

  • XAML+代码隐藏
  • 代码

在第一个例子中,您找不到Delete,因为您将类强制转换为Grid。

网格定义中没有Delete事件。

你应该这样做:

tbTextReadOnlyWithDeleteButton tbMit = new tbTextReadOnlyWithDeleteButton(1, 0, "Name", mit, "name", dat);
tbMit.Delete += your_event_handler;

我建议您使用XAML+代码隐藏方法。(没有人只使用代码来定义控件)

您可以右键单击Visual Studio中项目的任何文件夹,然后选择"用户控件"。

您将自动拥有以下文件:

  • your_control.xaml
  • your_control.xaml.cs

C#+XAML:

c#:

public partial class your_control : UserControl
{
    public delegate void delete_event_handler(your_control sender);
    public event delete_event_handler delete;
    public your_control()
    {
        this.InitializeComponent();
    }
    private void on_bu_click(object sender, RoutedEventArgs e)
    {
        // the event is null if there is no listeners bind to it
        if (this.delete != null)
            this.delete(this);
    }
}

和XAML:

<UserControl x:Class="test_wpf.your_control"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <!-- Use the FieldModifier property to define the visibility of the control outside the class-->
    <TextBlock x:Name="tb" x:FieldModifier="private" >Your text</TextBlock>
    <Button Grid.Column="1" x:Name="bu" x:FieldModifier="private" Click="on_bu_click">Delete</Button>
</Grid>

然后

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        your_control control = new your_control();
        control.delete += on_delete;
    }
    public void on_delete(your_control sender)
    {
        // your stuff
    }
}

仅代码方法:

public class your_control : UserControl
{
    public TextBox tb { get; private set; }
    public Button bu { get; private set; }
    private Grid container;
    public your_control (/* your params*/)
    {
        this.tb = this.build_textbox();
        this.bu = this.build_button();
        this.container = new Grid();
        this.Content = this.container;
        this.container.Children.Add(this.tb);
        this.container.Children.Add(this.bu);
    }
    private TextBox build_textbox()
    {
        TextBox tb = new TextBox();
        return tb;
    }
    private Button build_button()
    {
        Button bu = new Button();
        return bu;
    }
}

然后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        your_control control = new your_control ();
        control.bu.Click += on_bu_click;
    }
    public void on_bu_click(object sender, EventArgs e)
    {
        // your stuff
    }
}