I want to pass list of checked Id (checkedParcels) to another page to display list of details accordingly.
For this in first ViewModel I have implemented command on which execution I am able to navigate to another page. Here is that code:
Uri uri = new Uri("/UnitListForParcelPage?checkedParcel=" + checkedParcels,UriKind.Relative);
navigationService.NavigateTo(uri);
I am able to navigate to second page here is address as it shown in browser:
http://example.com/PropMgmtTestPage.aspx#/UnitListForParcelPage?checkedParcel=System.Linq.Enumerable+WhereEnumerableIterator%601%5BPropMgmt.ParcelServiceRef.Parcel%5D
My problem is I am using ViewModel to perform operation on this page but I am unable to find any method to access value passed through query string.
Update:
On page code-behind I have added this code:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string PSTR = NavigationContext.QueryString["checkedParcel"];
MessageBox.Show(PSTR);
}
MessageBox is showing correct value now I just want to bind that to viewmodel property
I have used this approch to bind viewmodel to view:
<navigation:Page.Resources>
<helpers:SimpleViewModelLocator ViewModelKey="UnitTransFormViewModel" x:Key="viewModelLocator"/>
</navigation:Page.Resources>
<navigation:Page.DataContext>
<Binding Source="{StaticResource viewModelLocator}" Path="ViewModel"/>
</navigation:Page.DataContext>
Another way Make a public Property and Assign it with the Value of checkedParcel and now you can use it in the ViewModel Cheers :)
UPDATE:
Just make a
public static string checkedParcel = string.Empty;
in App.Xaml.cs
and When you call
App.checkedParcel = checkedParcels;
this.navigationService.NavigateTo(uri);
before that you need to give the Value to App.checkedParcel =checkedParcels;
and in your Navigated page mathod
protected override void OnNavigatedTo(NavigationEventArgs e)
{
string PSTR = App.checkedParcel;
MessageBox.Show(PSTR);
}
Hope You Understand. You can Achieve this by Making a Property and Setting Accordingly.
You could use a broadcast service (like Messenger if you're using MVVM Light) to send the 'change view' notification, along with your parameter.
Then you'd have easily the View react (Navigate) and the ViewModel get its parameters.
Related
I have a user control with a button which when clicked opens a new user control.
private void Button_Click(object sender, RoutedEventArgs e)
{
Window window = new Window
{
Title = "Window2",
Content = new UserDataControl2()
};
window.ShowDialog();
}
I need to pass a collection to the new user control. How can I do it?
The easiest way is to create a custom constructor for your user control.
// Button_Click event
Window window = new Window
{
Title = "Window2",
Content = new UserDataControl2("My Data");
};
// User Control class.
string _info;
public UserDataControl2(string info)
{
_info = info.
};
You could also create a method or property in the user control to receive the data as well. Use whichever seems more appropriate in your context.
The best way is passing object to DataContext of this Window. For this you will need to create a class where store this parameters (ViewModels) and after "binding" to the Window (View). After you can pass this object assigning to Datacontext.
Look to MVVM model to understand better what I mean.
MVVM Pattern Made Simple
MVVM in Depth
This is my situation:
- I have a WebApi that sends me a json data.
- My app reads this data and binds all information in a list box
- When I tap on Item of the list box I want to show all information about that item
The problem is: How can I bind data on the new view?
This is the code after tap (MainViewModel):
this.ProfessorDetail = new RelayCommand(() =>
{
if (SelectedIndexProfessors != -1)
{
//This variable contain all detail information
Professor x = Professors.ElementAt(SelectedIndexProfessors);
//Open new page
App.RootFrame.Navigate(new Uri("/Pages/ProfessorDetailPage.xaml", UriKind.RelativeOrAbsolute));
}
});
You can use Uri parameter to pass simple string information between pages. For example, in your RelayCommand pass unique information about selected professor :
.........
//pass selected professor Id to ProfessorDetailPage
App.RootFrame.Navigate(new Uri("/Pages/ProfessorDetailPage.xaml?professorId=" + x.ProfessorId, UriKind.RelativeOrAbsolute));
.........
Then in the ProfessorDetailPage's Loaded or NavigatedTo event handler get the uri parameter and display information accordingly :
.........
string professorId;
if(NavigationContext.QueryString.TryGetValue("professorId", out professorId))
{
//load information based on professorId parameter value
}
.........
I never made a page based application, but I was looking at this link and from basic knowledge of WPF, I do know you need to set the DataContext of that page just like you asked.
Take a look at the following code in the link:
this.Frame.Navigate(typeof(BasicPage2), tb1.Text);
That is sending the text entered in tb1 to the object you're navigating to. Then look at how the receiving object is utilizing that information:
private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
string name = e.NavigationParameter as string;
....
}
You're going to want to follow the same idea, except you're going to want to do something like:
App.RootFrame.Navigate(new Uri(".....", ...), x);
And then in the page itself, you're going to want to set up a LoadState event in ProfessorDetailPage control and inside it do:
Professor prof = x as Professor;
if( prof != null)
{
this.DataContext = prof;
}
That should set the DataContext of ProfessorDetailPage and your data should be populated.
Let me know how it works out, hope this helps!
I'm using C# WPF MVVM. So in XAML there is a listview, which is binded to an object, used to show different information from sql database depending on tab.
For example. I have two forms: one is that shows information and another that is used to input information. How can I automatically update the listview in one form, after new information was entered in another form? Because now I have to switch tabs to get the listview updated.
binding direction for this element should be exposed to TwoWay (Mode=TwoWay)
like this:
x:Name="list"
ItemsSource="{Binding ....... , Path=........., Mode=TwoWay}}" ......
Apart from the default binding, which is one way, you can also configure binding to be two way, one way to source, and so forth. This is done by specifying the Mode property.
OneWay: Causes changes to the source property to automatically update the target property but the source does not get changed
TwoWay: Changes in the source or target automatically cause updates to the other
OneWayToSource: Causes changes to the target property to automatically update the source property but the target does not get changed
OneTime: Causes only the first time change to the source property to automatically update the target property but the source does not get changed and subsequent changes do not affect the target property
you can look this : http://msdn.microsoft.com/en-us/library/ms752347.aspx
After you enter new information into a form, try to invoke your own method, which will update your information into a list view.
So you can use some event eg. DataContentChanged or your update method can be called when u click the button which adds new data into your form.
Example of refresh method should look like this:
public void lbRefresh()
{
//create itemsList for listbox
ArrayList itemsList = new ArrayList();
//count how many information you wana to add
//here I count how many columns I have in dataGrid1
int count = dataGrid1.Columns.Count;
//for cycle to add my strings of columns headers into an itemsList
for (int i = 0; i < count; i++)
{
itemsList.Add(dataGrid1.Columns[i].Header.ToString());
}
//simply refresh my itemsList into my listBox1
listBox1.ItemsSource = itemsList;
}
EDIT: To finish and solve your problem, try to use this snippet of code:
//some btn_Click Event in one window
//(lets say, its your callback " to update" button in datagrid)
private void Button_Click_1(object sender, RoutedEventArgs e)
{
//here you doing somethin
//after your datagrid got updated, try to store the object,
//which u want to send into your eg. listbox
data[0] = data; //my stored data in array
//for better understanding, this method "Button_Click_1" is called from Window1.xaml.cs
//and I want to pass information into my another window Graph1.xaml.cs
//create "newWindow" object onto your another window and send "data" by constuctor
var newWindow = new Graph1(data); //line *
//you can call this if u want to show that window after changes applied
newWindow.Show();
}
After that your Graph1.xaml.cs should look like this:
public partial class Graph1 : Window
{//this method takes over your data u sent by line * into previous method explained
public Graph1(int[]data)
{
InitializeComponent();
//now you can direcly use your "data" or can call another method and pass your data into it
ownListBoxUpdateMethod(data);
}
private void ownListBoxUpdateMethod(int[] data)
{
//update your listbox here and its done ;-)
}
So, in the Windows Phone 7 app I'm making, I use a ListBox with a SelectionChanged event handler to navigate a user to a new webpage, showing additional information. The MainPage.xaml shows a ListBox populated with information from a JSON file, which works correctly. However, if a user wants to read more about the news, he/she will have to click on the news in the ListBox, which fires the SelectionChanged event, which looks like this:
private void NewsList_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
int index = NewsList.SelectedIndex;
fetchNewsContent newsContentGetSet = new fetchNewsContent();
newsContentGetSet.newsID = newslistJson.ElementAt(index).news_id;
newsContentGetSet.newsTitle = newslistJson.ElementAt(index).news_title;
newsContentGetSet.newsAbstract = newslistJson.ElementAt(index).news_abstract;
newsContentGetSet.newsContent = newslistJson.ElementAt(index).news_content;
newsContentGetSet.newsAuthor = newslistJson.ElementAt(index).news_author;
newsContentGetSet.newsDatePublished = newslistJson.ElementAt(index).news_date_published_no;
//object[] someobject = { newsContentGetSet.newsID, newsContentGetSet.newsTitle, newsContentGetSet.newsAbstract, newsContentGetSet.newsContent, newsContentGetSet.newsAuthor, newsContentGetSet.newsDatePublished };
NavigationService.Navigate(new Uri("/NewsPage.xaml?obj=" + index, UriKind.Relative));
}
This simply uses a class (newsContentGetSet.cs) with getters and setters for each of the strings (newsID, newsTitle, etc.), but when the SelectionChanged is fired, it the .cs file doesn't set the newly given newslistJson values! Why?
I also tried sending only text parameters in the NavigationService, but the newsContent string was too long (whole news story), so it returned an "shell page uri too long" error.
Right now, this sends simply the index int to the NewsPage page, which tries to capture the values, but fails since the newsContentGetSet doesn't actually set anything (doesn't debug into it when I try). Aaany ideas, really?
Instead of passing the data on parameter. You should save the data to variable into App class and then retrieve them from there when you have navigated to next page.
App.xaml.cs
public static fetchNewsContent newsContentGetSet;
Accessing it
var fetchedNewsContent = App.fetchNewsContent;
You can store/retrieve the data from any page. Note that if the application is closed the data is gone.
Within my Website project, I have some aspx pages, javascript files, and a custom C# class I called MyCustomReport. I placed a Image box with an ID of Image1 inside SelectionReport.aspx. I need to get access to that Image1 inside MyCustomReport.cs so I can turn it on and off based on conditions. What code do I need to do this? Thanks everyone
You'll need to pass the instance of Image control to MyCustomReport. From there you'll be able to set it's Visible property to true or false.
Probably something like this
public partial class SelectionReport : Page
{
// your code here
protected void Page_Load( object sender, EventArgs e ){
MyCustomReport myCustomReport = new MyCustomReport();
myCustomReport.MyReport( Image1 );
}
}
public class MyCustomReport
{
public void MyReport( Image arg ){
// some more code
arg.Visible = false; // or true
}
}
EDIT derek is right, you won't need the entire page, just the image.
it sounds a bit odd to do it that way. You could pass the control to the class method using the ref keyword, then the class could modify it:
doSomething(data, MyUserControl);
I think a better implementation would be for your class to have a method or property that the page could query to turn the control on or off.