I'm having a hard time building a filtering system in Sitecore 7.
I have 2 sublayouts, on the same level of the page.
Sublayout A is a sidebar that contains a list of checkboxes and has an event that populates a List with the selected values.
Sublayout B displays a set of items.
What I would like to do, is send the populated List from sublayout A to sublayout B in order to filter the items list based on what the user selected.
I was able to do this by passing the data through Session, but this is not an optimal way of handling that data.
I've tried defining a property for sublayout A and loading the list there, but I can't get the exact instance of sublayout A from sublayout B in order to read the populated property.
Also, trying to Page.FindControl("IdOfSomeElementFromSublayoutA") always returns null in Sublayout B. Even though I've casted Page as the .aspx page that contains both Sublayouts.
I'm using Sitecore 7 Update 2.
Thanks a lot for your time.
The best way to do this is by raising (and subscribing to) events using the Sitecore.Events.Event class. Your sidebar sublayout would raise an event using something like the following within a button's click event handler:
Sitecore.Events.Event.RaiseEvent("YourEventName", new YourEventArgsClass { Property = "SomeValue" });
then in the other sublayout you would need to have the following set up in order to handle the event:
public partial class YourOtherSublayout : System.Web.UI.UserControl
{
private System.EventHandler eventHandlerRef;
protected void Page_Load(object sender, EventArgs e)
{
eventHandlerRef = EventHandlerMethod;
Sitecore.Events.Event.Subscribe("YourEventName", eventHandlerRef);
}
protected void Page_Unload(object sender, EventArgs e)
{
if (eventHandlerRef != null)
{
Sitecore.Events.Event.Unsubscribe("YourEventName", eventHandlerRef);
}
}
private void EventHandlerMethod(object sender, EventArgs e)
{
if (e != null)
{
//do stuff here
}
}
}
Note: it is important to keep the Page_Unload code there otherwise you will see the EventHandler method being called multiple times.
Related
I have two DropDownList with OnSelectedIndexChanged="SelectedIndexChanged" but I need to know in the C# code withch one is the one I used.
How can I know that?
Answering the questions:
I'm using Web Forms and I'm trying to change some GridViews Source from a choseen option in a DDL but the web had the same DDL (with different IDs) in several places and I can't delete them...
The general form for an event handler is:
OnSomeEvent(object sender, EventArgs e)
sender is a reference to the object that is raising the event.
In your case, sender is a reference to the DropDownList whose selected index has changed. So you should use something like this:
private void SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList the_list_that_changed = (DropDownList)sender;
int ids = the_list_that_changed.SelectedIndex;
}
The first parameter sender represents the object raising the event. Hence the Sender reference to your DropDownList whose triggered the selected index changed.
private void SelectedIndexChanged(object sender, EventArgs e)
{
if (((DropDownList)sender).ID == "firstDropDownID")
{
//To Do for first dropdown
}
else
{
//To Do for second dropdown
}
}
Basically I have a longlistselector and it contains writings when one of them is selected I am going to navigate to a page and its going to show the all detailed information of this writing (article , date , image etc.)
Don't worry about the data, I checked and data contains the details all I need is how to send this Writing object (named data) with navigating.Or can you give any suggestion how can I do this but without using uri query
Thank you
private void longList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
LongListSelector selector = sender as LongListSelector;
Writing data = selector.SelectedItem as Writing;
NavigationService.Navigate(new Uri("/WritingPage.xaml", UriKind.Relative));
}
To pass an Object from one page to another PhoneApplicationservice is easiest way. Here is the simple example to pass Object from one page to another. Its tested.
private void longList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (PhoneApplicationService.Current.State.ContainsKey("Data"))
if (PhoneApplicationService.Current.State["Data"] != null)
PhoneApplicationService.Current.State.Remove("Data");
LongListSelector selector = sender as LongListSelector;
Writing data = selector.SelectedItem as Writing;
PhoneApplicationService.Current.State["Data"] = data ;
NavigationService.Navigate(new Uri("/WritingPage.xaml", UriKind.Relative));
}
//On second page
//I assume you want to Data on page load
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Writing data = new Writing ();
data =(Writing)PhoneApplicationService.Current.State["Data"]
PhoneApplicationService.Current.State.Remove("Data");
}
Are you coding in MVVM ?
If yes, you can send and register to an Event (published by your ViewModel linked to the LongList and subscribe this event in your ViewModel linked to WrittingPage.)
Simple and better way is to make "Writing" object scope Global.
Here, I added a class file to solution "Global.cs" and I declared "data" variable of "Writing" type.
public static Writing data = new Writing();
Use the same code you did and access the "data" variable here. I have done some minor change to your code.
private void longList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
LongListSelector selector = sender as LongListSelector;
Global.data = selector.SelectedItem as Writing;
NavigationService.Navigate(new Uri("/WritingPage.xaml", UriKind.Relative));
}
Now access "data" variable on "WritingPage.xaml" after you navigate to it. Use value of this variable and then make it null.
I am using visual studio 12, coding in asp.net using c#.
I have 3 dropdownlists in my code, all of which are bound by lists that I created.
I need some advise as to which method is better to call the postbackvalues of ddl's to perform a task.
Option 1
When a user selects an item from drop down list 3, the postbackvalue is sent from Dropdownlist3_SelectedIndexChanged to the dropdownlist2_selectedindexchanged by calling the method. Only after I have both the postbackvalues I would like to produce a chart. Regardless of what the chart holds and regardless of what the data is in the drop down list.
So something like
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
// I would like to have the postbackvalue of drop down list 3 here so i can use its value and dropdownlist2's postbackvalue to produce a chart.
}
and in the dropdownlist3
protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
{
// I would like to call DropDownlist2_SelectedIndexChanged(...) method so I can send the postbackvalue of DDL3 for use in DDL2.
}
Option 2:
Define a global variable that stores the postbackvalue of Dropdownlist3 and use that value in Dropdownlist2_SelectedIndexChanged method for further use such as produces a chart.
I have read a lot about global variables but do not understand the con's about them.
I am not sure if this is what you are after, but perhaps having a third method which is called that handles the updating of the chart...
for example
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
BuildChart();
}
protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
{
BuildChart();
}
private BuildChart()
{
var ddl3Value = DropDownList3.SelectedValue;
var ddl2Value = DropDownList2.SelectedValue;
if(ddl3Value != null && ddl2Value != null)
{
//build chart.
}
}
I have a UserControl, which is basically a wrapper for a GridView that needs to send a message every time a cell content (of the GridView) is changed. Usually, that could be solved like this:
private void MainDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
var editingTextBox = e.EditingElement as TextBox;
doSomething(editingTextBox.Text);
}
The problem is that I don't know the type of EditingElement (which comes as a FrameworkElement) so I cannot do the conversion. And in that moment, the currentCell.SelectedValue is still the original value. I also don't have control over the model (where I could implement INotifyPropertyChanged and use it to catch the changes).
Is there some simple way I am missing? Or how would you go about implementing this? Thank you for any suggestions.
Wrapping your model within a CollectionView and use this for the binding.
myCollectionView = (CollectionView)
CollectionViewSource.GetDefaultView(rootElem.DataContext);
This will provide you a INotifyPropertyChanged interface.
Update
Sorry my first answer was somewhat misleading.
If you're not able to change the model, you should create a view model. The view model, implementing INotifyPropertyChanged can provide the needed change events without any knowledge of the current view. This way the view doesn't depend directly on the model.
Futher reading:
The role of the model in MVVM
I have found a very simple solution (can't belive I haven't seen that one) composed of catching two events from the DataGrid.
Here is the code:
private object changedRow;
private void MainDataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
changedRow = e.Row.Item;
}
private void MainDataGrid_CurrentCellChanged(object sender, EventArgs e)
{
if (changedRow != null)
{
// do something with the edited row here
changedRow = null;
}
}
I'm using a form to populate a gridview with x users. However I want whenever I call the function if there is only 1 user displayed inside the gridview to autoselect that first user.
So within my callback function I have
if (users.count == 1)
{
// Do something
}
I currently use the following function upon someone pushing "select" alongside the gridview.
Users_SelectedIndexChanged(object sender, EventArgs e)
It would be nice if I could reuse this function and do something like
if (users.count == 1)
{
Users_SelectedIndexChanged(object sender, EventArgs e);
}
Use the GridView.SelectedIndex property.
Setting this property to 0 after binding the data and checking for at least one item ought to do the trick. Technically you could call the event handler method, but to no end other than executing your own implementation.
I would use the GridView's OnLoad method and call your function there. Data has been bound when the OnLoad method is called.
public void GridView_OnLoad(object sender, EventArgs e)
{
//Assuming one row means 1 user and gv is your gridview object
if (gv.Rows.Count == 1) //(user.count == 1)
{
//call your selected function here
}
}