Unabe to get gridview reference from user control on a popup
-
Friday, June 22, 2012 10:05 AM
Based on another post , I've implemented a light dismiss popup (user control) to have the user enter in the values for a new item. I can add that to the my collection, but of course, as I and others have posted, it's hard to get the gridview to refresh itself with the new items.
I have my main data source loaded in app.xaml.cs, then in my main page, it's assigned to my items in LoadState as such:
List<IceCreamSource.GroupInfoList<object>> data = (navigationParameter as IceCreamSource.StoreData).GetGroupsByLetter(); cvs2.Source = data; (semanticZoom.ZoomedOutView as ListViewBase).ItemsSource = cvs2.View.CollectionGroups;So in my additem user control, I add the item to my collection with the following code but I can't find the GridView element so that I can update the data source again.
private void AddNewitem(object sender, RoutedEventArgs e) { IceCreamSource.Item myNewItem = new IceCreamSource.Item(); TextBox TitleTextBox = (TextBox)this.FindName("NewTitle"); myNewItem.Title = TitleTextBox.Text; IceCreamSource.StoreData data = (Application.Current as App).Treats; data.Collection.Add(myNewItem); GridView view = this.FindName("myGridView") as GridView; // view is null becaue it can't get to myGridView on my main page
view.DataContext = data; }
The issue is that "this" is the user control and "this.Parent" is the popup. How can I get a reference to my gridview on my main page (from which I launched the add item user control via an app bar "add" button)?
All Replies
-
Saturday, June 23, 2012 2:53 PM
I've tried save a reference in my main page where the grid view is and save it as a public variable but I'm still not able to find a reference to the gridview. Without that, I can't update the data context and hence get my grid view to update.
Ideas?
-
Saturday, June 23, 2012 3:20 PM
I suggest to define an event from the control that's hosted in the popup. When the Add button is pressed, raise the event and pass the added item as event argument. Let the main page hook an event handler to it. It should find the gridview more easily - like this.TheGridView.
I'm doing something similar in this article, that was also mentioned in your other post.
-
Saturday, June 23, 2012 3:27 PM
Thank you. I'd read your article originally and am still somewhat new to the event handlers and accessing things across pages. I'll go through it again. Moments before you responded, I did actually get it to work but not as you suggest. I added a public variable to my app.xaml.cs and then in my main page, if that variable doesn't have a value I save the reference to the GridView. Then in my additem page, I do something likeGridView view = (Application.Current as App).myGridViewReference; view.DataContext = data;
The thing I don't like is that it feels like a "hack" by having a global variable. So I'll go back through your code again. I really do appreciate the input! -
Saturday, June 23, 2012 3:41 PM
I you want to stick to your global variable (which is fine), then I would suggest to assign it each time you enter the main page (e.g. in the OnNavigatedTo). When you leave a page and come back to it, you actually enter a new instance - with a new gridview. So you don't want the global variable to still refer to the old gridview.
-
Sunday, June 24, 2012 2:07 AM
I found that my solution with using a global variable isn't working 100% so I've downloaded your sample and have modified it slightly to have the user enter in a string on the dialog and the close the dialog. My goal is to then retrieve that data in the MainPage.
I understand how you're calling the CloseRequested event handler but I'm trying to figure out how to pass that data as an event argument. I tried modifying the SaveButton_Click function to pass in the string they entered to the call this.CloseRequested as shown below but it won't compile. I'm thinking I need to find the right type of event so I can pass a string in the args.
private void SaveButton_Click(object sender, RoutedEventArgs e) { if (this.CloseRequested != null) { //this.CloseRequested(this, EventArgs.Empty); this.CloseRequested(this, (EventArgs)this.NewName.Text); } }I'm wondering if I need to define my own event handler as described by the link below.
http://msdn.microsoft.com/en-us/library/118wxtk3(v=vs.110)
I've read through the article but will need more time to fully understand it. I'm also wanting to make sure Im not headed down the wrong path and wasting time when there might be a simpler solution.
- Edited by Lisa19 Sunday, June 24, 2012 2:24 AM Added link
-
Sunday, June 24, 2012 5:50 AMYou need to start with defining your own EventArgs subclass with a property to hold the event information (the 'Text' in your case). An instance of that class will send the event information from the event raiser (Dialog) to the event subscribers (Main page). More info here.
-
Sunday, June 24, 2012 2:17 PM
as I see, this is not what you are looking for an answer to, but just a small suggestion...
why don't you use the same DataContext (ViewModel) for the usercontrol and the page (if they are always used together), and a binding to some parameter that you want to collect from the popup. This way there is no need to pass traverse the UI controls or global variables...Which is the whole point of MVVM.
Can Bilgin
Blog CompuSight -
Sunday, June 24, 2012 3:52 PM
Thanks for the input. I learn best by example and since I've Diederik's example, I see how the view model is not actually in the code behind for the page and it's more centralized. However, this is my first experience with any of the MVVM stuff and am still learning obviously. :)
What I'm not understanding in your statement is the "a binding to some parameter that you want to collect from the popup". If the main page's view model and the user control have the same data context, can I just add an item to the data context before I close the model? I guess the question is then would that cause my gridview to update.
Might you provide a sample? To clarify, I'm not asking for the "answer", but an example will help me compare that to Diederik's sample that doesn't provide an add item.
-
Sunday, June 24, 2012 4:23 PM
you are absolutely right... the popup and the page actually share a data model...
With a simple example, say you have a bool property that decides on the visibility on a item (bound to a control's visibility property, with a booleantovisibility converter) on the page. You can bind this TwoWay to a checkbox in the popup which would adjust the view on the main page.
Can Bilgin
Blog CompuSight -
Sunday, June 24, 2012 5:23 PMBased on some posts I've read over the last month or so, it seems that MVVM for Metro is a smaller set of features than for WPF. Would you suggest that I simply go to MSDN and search for Metro and MVVM or do you know of some good tutorials out there that would help bring me up to speed on this topic?
-
Sunday, June 24, 2012 5:48 PM
I think the best examples are the implementations for the template project on WinRT... If you want to be fast and productive, I would just go through the implementation of the sampledatasource (the model, which you can replace with anything from feeds, to wcf service data), the DefaultViewModel from LayoutAwarePage which is an observable dictionary ( the view model, and can be changed to your own class that implements INotifyPropertyChanged and last but not least the GrouppedItemsPage, CategoryDetailView, and the ItemDetailView which are the views.
Of course a more thorough reading and research on MVVM would help but it can get quite confusing when it goes too theoretical and generic.
Can Bilgin
Blog CompuSight- Proposed As Answer by Alejandro Campos MagencioMicrosoft Employee, Moderator Wednesday, June 27, 2012 1:26 PM
- Marked As Answer by Lisa19 Wednesday, June 27, 2012 1:58 PM
-
Monday, June 25, 2012 2:17 AM
I've used a variety of the templates in Visual Studio. I started with the grouped items page but didn't know at the time how to change the groupings of my items (View by size, view by brand, etc.) and I found that functionality in the semantic zoom with grouped grid view. Sometimes the Metro examples are based on Page and others as well as the VS templates are based on LayoutAwarePage so for newbies it's more difficult to know the reason why we should choose one over the other.
Thanks for the input. I'll keep "digesting" it and see what I come up with.
-
Wednesday, June 27, 2012 1:58 PMI'll mark the reploy by Cal as an answer because it makes sense but I still don't have this working in my app.
-
Saturday, June 30, 2012 3:07 AM
I'm still really stuck here. :( I've started another VS solution based on the Grid App (instead of semantic zoom) so I have the Grouped Items Page, Group Details page, etc. I've added my Add button in the app bar and have a popup to capture the data values. I just can't figure out how to get that data into the collection. Using the global variable approach with a reference to the GridView is not always working. I have to believe there's an easier way. Can someone help with a code sample?
Here is what I have:
<!-- AddItemPage.XAML --> <UserControl.Resources> <model:Materials x:Key="Materials"/> </UserControl.Resources> <Grid Margin="0,0,0,74" Width="400" Height="280" > <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock Text="Brand:" Grid.Row="0" Grid.Column="0"/> <TextBlock Text="Size:" Grid.Row="1" Grid.Column="0"/> <TextBlock Text="Material:" Grid.Row="3" Grid.Column="0"/> <TextBox x:Name="NewBrand" Grid.Row="0" Grid.Column="1"/> <TextBox x:Name="NewSize" Grid.Row="1" Grid.Column="1"/> <ComboBox x:Name="MaterialList" SelectedItem="{Binding Material, Mode=TwoWay}" ItemsSource="{Binding List, Source={StaticResource Materials}}" Grid.Row="3" Grid.Column="1"/> <StackPanel Orientation="Horizontal" Grid.Row="4" Grid.Column="1" > <Button x:Name="Add" Click="AddNewitem" Content="Add Item" /> </StackPanel> </Grid>My code behind has:
private void AddNewitem(object sender, RoutedEventArgs e) { Item myNewItem = new Item(); TextBox TitleTextBox = (TextBox)this.FindName("NewBrand"); myNewItem.Brand = TitleTextBox.Text; TextBox SizeTextBox = (TextBox)this.FindName("NewSize"); myNewItem.Size = SizeTextBox.Text; ComboBox Material = (ComboBox)this.FindName("MaterialList"); myNewItem.Material = Material.SelectedItem.ToString(); // ok - how do I reference the CollectionViewSource to add my item? }My Grouped Detail Page.XAML has this as a resource, which is based on the VS template and uses their SampleDataSource.
<Page.Resources> <!-- Collection of items displayed by this page --> <CollectionViewSource x:Name="itemsViewSource" Source="{Binding Items}" d:Source="{Binding AllGroups[0].Items, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"/> </Page.Resources>I just don't seem to be able to wrap by brain around this and understand how to make the AddItemPage and the Grouped Detail Page share the same model so I can just add an item.
- Edited by Lisa19 Saturday, June 30, 2012 3:29 AM
-
Sunday, July 01, 2012 6:11 PM
I don't have the vs project teamplte code handy right now, but I do recall that it sets the DataContext of the LayoutAwarePage. Can you set the DataContext of the popup to the same object that is being set to the LayoutAwarePage?
Hope this helps!
-mark
Program Manager
Microsoft
This post is provided "as-is"- Marked As Answer by Lisa19 Monday, July 02, 2012 4:05 AM
-
Monday, July 02, 2012 4:05 AM
Mark - I was able to get some sample code from Iris here (http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/fdc1ff67-09d4-4cb5-aae9-40c11fcf7b94) and from there see how to set the data context as you suggested.
<UserControl.DataContext> <viewmodel:MainPageViewModel/> </UserControl.DataContext>
I had to do some other things like put the ObservableCollection into the MainPageViewModel class so it could be referenced by both the main page and the popup.


