I'm working on a WPF app, where most of the controls are created dynamically at runtime. To save some code, I've created various static controls. Now, I want to create a textbox control with a delete button next to it. The point where I'm stuck now is, how do I capture events of the controls? (see code)
Edit: As suggested I tried to create a custom control. However, I can't get the custom event working. Ie in the wpf-page I can't find the delete Event to hook a handler to it. Where did I go wrong? So far I found out, that when I drop the : Grid
statement, the Event is shown.
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??
End Edit
// 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;
Has anyone a hint, of how to approach this?
Thanks!
You have 2 solutions to define your user control:
In your first example, you can't found Delete cause you are casting your class to a Grid.
There is no Delete event in the Grid definition.
You should do this :
tbTextReadOnlyWithDeleteButton tbMit = new tbTextReadOnlyWithDeleteButton(1, 0, "Name", mit, "name", dat);
tbMit.Delete += your_event_handler;
I would suggest you to use the XAML + code behind approach. ( no one only use the code to define a control )
You can rigth click on any folder of your project in Visual Studio, and then select User Control.
You'll automatically have these files:
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);
}
}
and 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>
and then
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
}
}
The code only approach :
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;
}
}
and then :
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
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.