捕获在一个来自Class的通用按钮的Click Click事件

时间:2016-07-25 07:14:52

标签: c# wpf

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

编辑: 正如建议我尝试创建自定义控件。但是,我无法使自定义事件正常工作。即在wpf页面中,我找不到删除事件来挂钩处理程序。我哪里做错了?到目前为止,我发现,当我删除: Grid语句时,会显示事件。

  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;

有没有人提示如何处理这个?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

  • XAML +代码隐藏

在您的第一个示例中,您无法找到删除,因为您正在将您的课程转换为网格。

网格定义中没有删除事件。

你应该这样做:

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
    }
}