How to access Parent Form public variables, control properties and methods? (WinForms C#) - winforms

I have Parent Form (FrmMainMenu) that has 3 panels. A panel1 docked on top and a panel2 docked on the left. The 3rd panel will be my container for the child Forms. I have a Title label (lblTitle.Text = "Home") on panel1 and buttons on panel2. I'm trying to emulate a Blazor look and feel (navbar and sidebar). My question is how can I access/manipulate the Title label (lblTitle.Text) on my Parent Form (FrmMainMenu) from a Child Form?
1. On Control Properties:
Example Event: When opening the child form I want the (lblTitle.Text) properties be changed according to child form function. ex. (lblTitle.Text = "List of Rooms"). And when closing the child form I want the (lblTitle.Text = "Home") go back to its original Text properties.
2. Methods: I have a method (public void ResetColors()) on my (FrmMainMenu) that can reset the colors on my buttons. Despite being public method my child form cannot access the method. This is also true to public variables.
Any suggestions is appreciated.
I tried converting private methods and variables into public. I also tried changing the control Modifiers to public. I still can't access Parent Form control properties and public methods.

I got it.
((frmMainMenu)this.ParentForm).lblTitle.Text = "List of Rooms";
On closing child form:
((frmMainMenu)this.ParentForm).Reset();
((frmMainMenu)this.ParentForm).lblTitle.Text = "Home";

Related

WPF using a view to change the parents atributes

My program has several views that are controlled using a Hamburger menu. Inside one of these views i have made a toggle switch to change between fullscreen and windowed. The only problem is that to do this i need to change the Mainwindow.xaml from within the view. The mainwindow is a "MetroWindow"
I have tried adapting the following:
Window parent = Window.GetWindow(this);
This works fine but when i want to use a metro specific attribute:
Parent.IgnoreTaskbarOnMaximize = true;
It obviously doesn't contain a reference as its not a window its a metrowindow. I changed the code to a metrowindow but that wont work as it cant convert from windows.window to mahapps.metro.controls.metrowindow.
MetroWindow metroParent = MetroWindow.GetWindow(this);
Is there anyway i can do this or run code from the mainwindow code within my view ?
Cast the result:
MetroWindow parent = Window.GetWindow(this) as MetroWindow;

Lightswitch modal window

I've got standard CreateNewEntity screen. Entity can contain list of entities of some other type. By default there is an add button that opens modal window when user wants to add another entity into collection. However, default modal window was lacking some of the needed functionality so I've done a bit of research. Turns out that default modal screens cannot be modified. So, I found a nice custom modal window helper class. The problem is that I can't seem to be able to access modal window fields in order to enforce needed logic. There are two dropdown lists that are associated. Change in one will result in limiting the other dropdown list options. I'm stuck at this particular part:
var proxy = this.FindControl("DodavanjeParcele");
proxy.ControlAvailable += (s, e) =>
{
var ctrl = e.Control as System.Windows.Controls.Control;
//how to obtain access to ctrl fields?
};
"DodavanjeParcele" is custom modal window. Before this, modal window is instantiated and initialized. It pops up after button click and functions as expected. The only thing missing are above-mentioned rules. I need to set change event handlers for modal window fields in order to define rules. As seen above I tried to cast IProxy as a standard Windows control. This is where I got stuck. I can't seem to find a way to access control fields and set event handlers. Any thoughts?
If I understand you correctly, I'm not sure why you need to search through controls or cast anything.
Control1 is an entity which creates an AutoComplete Box (dropdown list). That selection is copied into a local property in the Control1_Changed method. That property is used as a parameter in a filter query to create Control2.
C#:
private void Control1_Changed()
{
this.MyLocalProperty = this.Control1.SelectedItem;
}
VB.NET:
Private Sub Control1_Changed()
Me.MyLocalProperty = Me.Control1.SelectedItem
End Sub
Just make sure you have Auto Execute Query checked in Control2's Properties and the second control should update and filter when Control1 changes the query parameter.
The code in my screen shots all takes place inside of Yann's Modal Helper so there is nothing special you need to do.

WPF : update parent form after canceling edit in child form (reset DataContext)

I have a parent form with a customers listing in a WPF datagrid.
Editing a line of the form is done in a child form: click on a button in a line, open child form using selected item of datagrid and assign it to child form datacontext.
When a PropertyChanged event is triggered in the child form, the line being edited in the parent form listing updates.
If I decide to cancel my current modification by clicking on a cancel button in child form, I restore the original values ​​of the edited customer: before editing I made a clone of to be edited customer. Then now I reset child form DataContext by setting it to null then to the cloned customer. This was the hack I read on SO about forcing DataContext to refresh with DataContext itself being changed, not properties on its objects.
After canceling edit, child form shows the values I expect (properties of cloned customer), while the associated line in parent form listing didn't update: still shows edited customer values.
How can I ask parent form to update itself? I'm afraid I lost some references between objects by reassigning child form datacontext to a new object (loosing link to parent form datagrid interesting line selected item).
Thanks for your guidance,
EDIT :
When I am ready to edit a customer in child form, I assign datagrid selected item to a static variable of my application since it's mono-user, so that it's easier to handle "current customer". When I cancel edition, this static variable value has changed, but maybe I have to assign it to parent form datagrid selected item back too?
I was right: after child form closes, I must update parent form datagrid collection, at right index, with updated object.
// update static variable
SocodifApp.Client = ((Client) Listing.SelectedItem);
ClientForm editClientForm = new ClientForm();
editClientForm.ShowDialog();
// Get modified static variable after child form closes and update datagrid collection
// relevant item
_dataContainer.Clients[Listing.SelectedIndex] = SocodifApp.Client;

Adding breadcrumb navigation to a WPF MVVM app using Caliburn

I have an existing WPF application following the MVVM pattern with the Caliburn-Micro framework. I have a new requirement to add an interactive breadcrumb to the UI. While I can render the breadcrumb without issue, I am stumped trying to determine how to handle activation when one of the crumbs is clicked by the user.
I have an n-level object graph where each object is a Conductor<T>.Collection.OneActive.
The UI is able to handle basic "navigation" by calling ActivateItem with the item for each conductor to activate. At the each level, I display the list of items and when one is clicked, it is activated. As long as the activated item has child items, the UI displays its list of child items. When one of those is clicked, that child is activated and so on.
I am able to build the breadcrumb trail by crawling this object graph from the active root item down to active child item and so on but I don't know how to re-activate an item when the breadcrumb is clicked because I have a reference to the item, not the conductor that contains/manages that item.
Any ideas?
Just had an idea that may be of some use. It sounds like the conductors are hierarchical so:
Use the event aggregator to fire a simple message type with a property that contains the viewmodel you want to activate
public class BreadcrumbNavigate
{
public IScreen Screen { get; private set; }
public BreadcrumbNavigate(IScreen screen) { Screen = screen; }
}
The conductors should all be listening for these type of messages; when they receive a message they should only respond to it if they are currently active, meaning only the leaf node of the breadcrumb trail will respond to the first message.
If the VM in the message is not a child of the conductor, the conductor should close itself and re-publish the aggregator message so that the next active conductor can handle it (not sure how well this will work since it depends on a conductor closing itself then propagating a message but like I said, it's just an idea).
Eventually the correct conductor somewhere up the tree will handle the message, and that conductor will have a child VM which matches the message - this is the navigation target and that's where the message propagation stops
Edit:
The above won't work due to conductors being active when they have active children - so scrap that!
Can you post more information about your setup?
As far as you've described it, it sounds like a simple breadcrumb nav scenario; in order to go back along the breadcrumb you just need to use TryClose() on the active item of the VM that you want to jump back to:
// on the VM that you want to navigate to...
public void NavigateToMe()
{
// Check if we have a child, if so try and close it...will close all children etc
if (ActiveItem != null)
{
ActiveItem.TryClose();
}
}
Obviously you can just wrap this in a helper method such as
public void NavigateTo(IConductActiveItem vm)
{
var iClose = vm.ActiveItem as IClose;
if(iClose != null)
{
iClose.TryClose();
}
}
So all you need in the breadcrumb is a reference to the VM, on checking it has a closeable child and calling TryClose() all child VMs/conductors should be closed below the selected child - obviously this will only work if the child of the VM is always an item conductor
this is assuming you are just using the following object graph:
Conductor -> Conductor -> Conductor -> Conductor

Silverlight navigation app usercontrol state

I have a navigation app with 5 pages. I also have a usercontrol with 3 radio buttons. This usercontrol is used by all 5 pages in my app. By default the first radio button is selected. However if the user clicks the 3rd radio button and I go to another page I want my usercontrol to still show that 3rd radio button as selected. How do I go about accomplishing this task?
There are several ways you could do this. Probably the most simple way is to create a class that has a property for the selected item of the radio buttons. Add an instance of this class as a resource to the application and then bind the radio buttons to this static resource.
public class MyState
{
public string SelectedRadioValue {get;set;}
}
In the App.xaml.cs in the Application_Startup add:
var state = new MyState()
Resources.Add("myState", state);
Then in the bindings you can set:
SelectedValue="{Binding Source={StaticResource myState},Path=SelectedRadioValue}"
There are other approaches you could take as well.
Is it possible to show this control outside of the View control? It sounds like it should be placed on the MainPage.xaml outside of the place where the views are displayed. This way the one control is used and its value can be made available to all of the views.
If you are just looking to save the state of the page as the user navigates between pages then the easiest way of accomplishing this is to set:
NavigationCacheMode="Required"
in the first element of the xaml for your page.

Resources