I have a WPF application where i use Frame to load Page'is. On the Page i call my custom contol <Controls:OrderDataGrid x:Name="cntrlOrderDataGrid" />.
On this control i have DataGrid what is filled with data when i navigate to the Page inside the Frame. Sometimes the loading takes a while and i need to know when the DataGrid finishes loading, so i have set the Loaded event:
private void dgOrders_Loaded(object sender, RoutedEventArgs e)
{ }
But i cant figure out could i notify the MainWindow that the DataGrid has ended loading. When i set the Loaded event to the Frame then its fired right away without waiting for my custom control with datagrid.
You need to effectively pass the event up.
The Page that holds the datagrid needs to add a new event; something like OrdersLoaded. When the datagrid finishes loading fire that event. The main window can then subscribe to that event, thus telling it when the orders are loaded.
public event Action OrdersLoaded;
private void dgOrders_Loaded(object sender, RoutedEventArgs e)
{
if (OrdersLoaded != null)
OrdersLoaded();
}
Related
I'm trying to create an Avalonia App which uses several UserControl Views by binding the content in the MainWindow to a property Content in the MainWindowViewModel.(I believe this is standard for MVVM).
I want to be able to handle user inputs such as tapping the screen, pressing buttons etc, while also letting those events to bubble up to the MainWindow so that all inputs from the user can be monitored. This would allow a generic handler which could be simply used update an inactivity timer.
The furthest events seems to be within the same UserControl however I would like to handle the event from the MainWindow. This would mean that everytime a new UserControl is created, the inactivity timer would still function without major changes.
Here is how I'm currently handling tap events on the UserControls:
public static event EventHandler<RoutedEventArgs> TapRegistered;
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void RegisterTap(object sender, RoutedEventArgs e) => IdleWindowView.TapRegistered?.Invoke(this, e);
I'm then simply picking that up on the ViewModel the UserControl.
Let me know if there's any information which could be helpful - I wasn't exactly sure what code to add.
You need to actually register a RoutedEvent via RoutedEvent.Register like this:
public static readonly RoutedEvent<RoutedEventArgs> FooEvent =
RoutedEvent.Register<RoutedEventArgs>(
"Foo",
RoutingStrategies.Bubble,
typeof(YourType));
and then call control.RaiseEvent(new RoutedEventArgs { RoutedEvent = FooEvent }); to raise it.
I was able to detect taps on the MainWindow (And all views), by adding a handler in the code-behind of the MainWindow as shown below:
this.AddHandler(TappedEvent, this.RegisterTap, handledEventsToo: true);
And simply sending an event to the ViewModel to update an inactivity timer as shown below:
private void RegisterTap(object sender, RoutedEventArgs e) => MainWindow.TapRegistered?.Invoke(sender, e);
I use the Layout Event Handler in order to set the focus to a specific field. So everytime the Layout event occurs, the focus will be set to that field.
My problem is that when I make something visible/invisible, the focus will be set again to this specific field which I don't want.
How to avoid that?
Is there a way to say "skip the Layout Event Handler next time" ?
or should I use another Event Handler instead of the Layout one?
I just want it to be set the first time, but the Load event does not seems to work as expected.
Code for Load event handler:
in the Designer.cs
private void InitializeComponent()
{
// other stuff automatically generated by windows
this.Load += new System.EventHandler(this.myControl_Load);
// other stuff automatically generated by windows
}
and in myControl.cs:
private void myControl_Layout(object sender, LayoutEventArgs e)
{
this.myTimeEdit.Focus();
}
From what I gather, you need to focus a particular control when a form is shown for the first time. First, you can try to set the TabIndex property to 0. In this case, this control will be focused on the first form showing.
Try also to focus the control on the Form.Shown event instead of the Load event.
You can use LayoutEventArgs.AffectedProperty property. Just check if its value is set to "Visible":
private void myControl_Layout(object sender, LayoutEventArgs e)
{
if (e.AffectedProperty == "Visible")
return;
this.myTimeEdit.Focus();
}
This must have been asked before, but I am fairly new and don't quite know how to express myself...
1) I have a UserControl that basically acts as a toolbar. I re-use the toolbar in each window, hence the need for a uc.
2) The toolbar is filled with buttons
3) the usercontrol doesn't act on the button (no code), but it should pass the event back to the parent window so the code in the parent window fires up.
How can I do this? Is this a routed event? any sample code in vb.net would be appreciated!
On you user control, you need events that you can fire when the buttons are clicked. Then in your form, you handle the events just like you do for every other control. IE:
public event Button1_ClickedEventHandler Button1_Clicked;
public delegate void Button1_ClickedEventHandler(object sender);
private void Button1_Click(object sender, EventArgs e)
{
if (Button1_Clicked != null) {
Button1_Clicked(this);
}
}
You can call the event whatever you want and pass whatever you want. Here you will notice I am NOT sending the button but THIS, which in this case should be the User Control.
I have this simple code, where when the user leaves the TextBox control, TreeView gets focused:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.treeView1.Nodes.Add("A");
this.treeView1.Nodes[0].Nodes.Add("A.A");
this.treeView1.Nodes.Add("B");
this.treeView1.Nodes[0].Nodes.Add("B.A");
}
private void textBox1_Leave(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Leave..");
this.treeView1.Focus();
}
}
If we execute this code the Leave event is fired twice:
Leave..
Leave..
But if we set focus to other control, only one Leave event is fired.
Is that a problem of the TreeView? Do you know any workaround? Should we report this to Microsoft?
Thanks,
RG
this.treeView1.Focus();
Do not use the Focus() method in an event handler that's called because of a focusing event, like Leave. If you need to prevent a focus change then use the Validating event instead. Setting e.Cancel = true stops it.
But do note that this isn't very logical to do so for a TreeView, there isn't anything the user can do to alter the state of the control. You'll trap the user. Maybe that was the intention, do make sure the user can still close the window. If not then you might need the FormClosing event to force e.Cancel back to false.
Given that there is no code there to wire up the event I'm guessing you did it from the designer which means a line of code such as
textBox1.Leave += new EventHandler(textBox1_Leave);
will have been added to the Form1.designer.cs, check this file to ensure the line doesn't exist more than once as for each time this line is run you will get an event trigger, so if you run the line 3 times the Leave event will fire 3 times when you leave the textbox!
HTH
OneShot
I have a simple user control that contains some buttons that fire events which I want to be handled by the page using the control. I have my code setup as such:
public event EventHandler Cancel;
public event EventHandler Confirm;
public void Confirm_Click(object sender, EventArgs e)
{
if (Confirm != null)
Confirm(this, e);
}
public void Cancel_Click(object sender, EventArgs e)
{
if (Cancel != null)
Cancel(this, e);
}
but when I try to call these from the page that is using the control's page load event I don't get any of the custom events
ASPX Code
<%# Register TagPrefix="btg" TagName="CustomControl" Src="~/Search/CustomControl.ascx" %>
<btg:CustomControl ID="btgControl" runat="server" ></btg:CustomControl>
could this be because my buttons in the user control are within an update panel?
You shouldn't be seeing methods. You should be seeing events.
In your parent page's load, you need to do this:
myUserControl.Cancel += new EventHandler(myUserControl_Cancel);
You can hit tab,tab to auto-generate the method stub. That will look like:
void myUserControl_Cancel(object sender, EventArgs e) {}
Then, this code will fire after it is called in the method of your user control. In order for that code to fire, you'll have to assign the events to button events on your user control.
edit: myUserControl is the id of your user control. Also, some would argue that event handlers should be in your page's init method.
edit:
Is your user control properly referenced in the page? i.e. Are you registering the user control in web.config or using the reference directive in the page?
Also, did you try cleaning the solution and rebuilding? If your user control is dynamically created/loaded, you'll have to wire up the events in the same scope as the instantiated control. In order to dynamically load the user control, you'll have to have a placeholder in your page and do the following:
UserControl control = Page.LoadControl("~/ControlPath/ControlName.ascx");
((MyUserControlClass)control).Cancel += += new EventHandler(myUserControl_Cancel); // etc...