Passing objects between user controls in WPF - c#

I have got an application that contains a series of input fields(TextBoxes, ComboBoxes etc.) When a button is clicked the user inputs are initialized into a new custom object. The content of the window is then replaced with a new UserControl (So I now have a blank view to display new information on).
I want to bind some of the method outputs from the object created in the first view, to text boxes in the new User Control which has been displayed.
the new object is created when the button is clicked so isn't initialized at the start.
But the obvious error is that the newObject I made in the first view doesn't exist in the context of the second view
Hope that sort of makes sense
any help appreciated

Instead of replacing the UserControls you can just Hide/Show them, this way you can access them in your other views.
But this is not a very good design and will be problematic in case a lot of controls are there in your window. Better approch would be to use MVVM and save the output of views in the MVVM properties etc.

Related

WPF create a button for each view, which will set it as the content of a ContentControl

I have a WPF, MVVM program whose MainWindow is separated into a ListBox sidebar and a main part with a ContentControl. I want to create a functionality that will populate the ListBox with a button for each view that I have in my project and set its command such that clicking it will set the content of the ContentControl to the associated view automatically, i.e. so that I don't have to manually enter code when adding a new view. Something like iterate through all view files or something like that.
EDIT:
Perhaps I'm AGAIN not clear enough.
What I have and can do - type like a monkey "new Button, yadda yadda" every time I add a new view to my project.
What I want - write a piece of black magic that goes something like "There are 6 views in this project, I'll just make 6 buttons each such that, when clicked, will navigate to the appropriate view, without the guy who wrote me having to write any additional line of code any time a new view is added".
How can I achieve that and is it such a good idea, to begin with?
For instructional purposes, I'll be calling your "view" class View.
Create some sort of collection object (List<View>, ObservableCollection<View>, etc.) to store all of the Views.
Assign this collection to a dependency property. I'll call it Views.
Declare a dependency property for the selected/active view. I'll call it SelectedView.
Bind ListBox.ItemsSource to Views.
Bind ListBox.SelectedItem to View.
Bind ContentControl.Content to View as well.
With the above setup, the ContentControl will display whatever View is selected in the ListBox.

"Correct" Way to Show New Controls in WPF

I'm designing a small helper utility with a simple UI. I'm working off the following mockup:
The execution flow is meant to be as follows:
User clicks "Other" radio button.
A textbox is presented and user is prompted to write in a response.
My question is: What is the "correct" way to achieve the UI change from the picture on the left to the picture on the right? My options seem to be either create a unique window for each, or have all of the controls on the same window and just play with the visibility of the controls.
There is no "correct" way really. It all depends on your requirements.
If you want the new screen to show up in a new window, then create a new window. If you want it to show up in the same window and simply replace the previous screen with the radiobuttons, then toggle the Visibility property of the individual controls or the parent Panel, preferably using a view model that has either bool or Visibility source properties that you have bound to in your view.

Create a UserControl from a Model - Share ViewModel Property between UserControl

I have created an UserControl that encapsulate two UserControl.
The first one is a "model" that can be changed by the User. It represents a ObservableCollection of TextBox. Each one of them is filled by the User.
My second UserControl will be a List of UserControl.
Each sub UserControl will be a list of textbox.
I want to be able to create my second UserControl by using the information of the first UserControl ==> Text in each Textbox used in tooltip of textbox.
So what I want is when the user add a field in the first usercontrol to be able to add the same field in each item of my second UserControl.
The black rectangle represents my model and the red rectangle represents my second usercontrol so the use of my model to create a UserControl.
Each UserControl owns his ViewModel.
Thanks in advance.
Hi please try the next architecture:
First User Control observable collection. The ObservableCollection supports event which will be raised when item will be added/deleted/etc. Submit on this event in your first user control view model.
Second User control let its view model be composed of ObservableCollections.
Share the EventAggregator (link here) between view models of your controls. First user control view model will be publisher and the second will be subscriber.
Each time when the observable collection of the first user control view model will be changed, publish the aggregator event to inform about the fact that this collection was changed.
Second user control will get the event and perform action (add/delete) on all its collection.
update
You can manage the sharing mechanism so that the EventAggregator will be the same reference, but the published object will have a key which represents a particular tab (for example the hash code of the tab), thus each subscriber will know if it have to response or not.
That's all. Try to perform that, I'll be glad to help if you will problems with the code.
Regards.

Multiple custom controls affects control visibility

Ok, this is going to be a 1000ft long question, but there's a lot to cover so here goes:
I am creating a paged items control, the purpose of which is to display very large collections in a paged format. I've created a repository on GitHub which can be found here. I have removed any styling for simplicity.
Upon starting the application, it looks like this:
This is pretty straightforward really, there's navigation buttons, an items per page selector but that isn't really important. The problem here is when you click the button "Open New Window".
This will open a new MainWindow, but on the first window, the collection disappears, as shown below:
The image above shows the old window in front, as you can see, there is no list of content as there is on the new window.
So, after smashing my head against a wall for a couple of hours, I am in need of assistance. I'll provide an overview of how the project is structured.
AnagramPagedItemsControl
The control being used for displaying the content is a custom control called AnagramPagedItemsControl, it is responsible for handling navigation between pages. I think the key property here is the PagedCollection.
The PagedCollection dependency property holds the collection which is bound to the Models property in the TestItemsViewModel.
TestItemsViewModel
This is the DataContext of the MainWindow, each window instance should create it's own view model. The CreateTestItems() method is responsible for creating the list of test items.
LazyPagedCollection
The purpose of this collection is to encapsulate the logic of a paged observable collection, it only loads pages when they are needed, hence the laziness.
It exposes methods like NextPage which are called in the AnagramPagedItemsControl when the user clicks on the various navigation buttons. The view model can also call navigation on the LazyPagedCollection, this allows the view model to call navigation without having to go through the view to do it.
TL;DR
When I create a new Window, the content of the previous window disappears. The problem is almost certainly with the control however I am stuck as to how to fix the problem.
This is quite a large problem to look at so I'd be very grateful for anyone who can look into it. Again, the source code is here, please feel free to suggest alternatives or pick out anything that I may have overlooked.
Had some time to spare, so:
The problem is the setter for the CollectionView property in the style for AnagramPagedItemsControl in generic.xaml.
This does not instantiate a new ListBox every time the style is applied; it will just create the one ListBox, the first time the style is created, and use that value over, and over again. So in effect, every instance of MainWindow shares the same ListBox.
You can see this by setting the Tag property of PART_CollectionView to (for instance) "1" in SetupBindings(ItemsControl PART_CollectionView). When you open a new window, you'll see that PART_CollectionView.Tag contains the same value you previously assigned.

C# ASP.NET - Dynamic MenuItems in a user control are randomly being duplicated outside of control creation

EDIT: I needed to skip control creation during post back -- see my answer below.
I'm working on a very basic front end to a simple tool and I wanted to present some data in a much more sorted and useful way, instead of making one huge wall of text. I found this tutorial on building a simple tabbed interface using MultiView, but have run into a bizarre problem. I can't use Ajax tabs because of legal hissy fits over 3rd party software.
My webpage is a basic ASP.NET page with a user control plopped in the middle of it. In this control's ascx file, I defined the Menu (empty) and the MultiView (also empty) so that I can dynamically populate the tabs with content driven from an external file.
When the default page's OnInitComplete function is called, I call through to the user control to load the data file, then build out the tabs and the view content based on the loaded data. I tried doing this from PageLoad, PreInit, and CreateChildControls, but I kept getting an errors saying that I was setting the the MultiView's active view index at an invalid time (and also that there were 0 views despite the fact I just added a bunch of them):
ActiveViewIndex is being set to '0'. It must be smaller than the
current number of View controls '0'. For dynamically added views, make
sure they are added before or in Page_PreInit event.
But OnInitComplete appears to work just fine, so I went with that.
I iterate over the loaded data (multiple lists of strings), and for each list, I add a MenuItem with the list's title to the Menu and a View to the MultiView. The View is populated with a table->row->cell as in the above tutorial. In the cell, I add the list title and a CheckBoxList data bound to the list of strings.
So far so good, but when I click on a tab (or one of the checkboxes, etc) and there is a postback or something like that (the screen flashes as the site redraws itself), there is now a duplicate set of MenuItems immediately after the original. Each time I click on a tab or checkbox, another set of menu items are added.
I clear the MenuItem's Items list prior to building the controls and I verify that the controls hierarchy is structurally as expected after the control construction. Yet when one of my callbacks is called, my MenuItem list magically has some items added to it. None of my other controls appear affected at all. As a hack, I can remove the duplicates manually in my menu's OnMenuItemClick event, but I'd have to do the same in any of the callbacks I receive. Obviously I'd rather prevent this from happening. This has me stumped and I haven't been able to find anything online about it. Why would one set of controls have some content duplicated, yet every other control maintain its state correctly? My code is really simple so there isn't a way to add additional menu items without also adding the views. Anyway, there are a correct number of items prior to clicking on the tab/checkbox, an additional set immediately following in the callback.
This is my first time using ASP.NET, so I'm learning as I go. :) Thanks!
My problem was that I was not testing for postback before creating the controls. The code below is working for me.
In my user control's code behind:
protected void OnInitComplete( EventArgs e )
{
if( !Page.IsPostBack )
{
CreateMyControls();
}
}

Categories

Resources