I have a RadGrid displaying a hierarchical structure. I want to save the expand/collapse state of each item in the grid so that when the user returns to the site, everything looks exactly as they left it. I have code to save and restore the state of expanded/collapsed items, however, I now need a way to detect which item is currently being expanded/collapsed when the user clicks on the expand/collapse icon. I know there's a command event, but there is no command argument nor does there seem to be any indication of which item's state is being changed. Any ideas?
I found that the GridCommandEventArgs passed into the RadGrid.ItemCommand event contains an 'Item' property that represents the item that was expanded/collapsed. If casted to a GridDataItem, one can retrieve the data key and do whatever manipulation is necessary.
protected void RadGrid_OnItemCommand(object sender, GridCommandEventArgs e)
{
try
{
if(e.CommandName.Equals("ExpandCollapse"))
{
string id = ((GridDataItem)e.Item).GetDataKeyValue("ID").ToString();
// ... do work on id (i.e. save state, etc.) ...
}
} catch(Exception ex)
{
// What could possibly go wrong? :)
}
}
Use Persistance Framework.
In my post here:
http://www.telerik.com/community/forums/wpf/persistence-framework/presistenceframework-not-save-groups.aspx#2248287
there is example how to do this.
Related
I have an overview of some objects, displayed in a listView.
When an object is selected I want to show a form containing more details about the selected item.
public lessonForm(lesson foo)
[get and display data]
[...]
lessonListView.ItemActivate += lessonSelected;
void lessonSelected(object sender, eventArgs e)
{
lesson ??? = //REQUESTION MAGIC here.
new lessonForm(???).Show();
}
Since ListViewItems are acutally just texts and not programmatically connected to the lesson-object I used to create them, I have not found a proper way to find the respective lesson-object for each listViewItem.
Sure I could do
lesson ??? = Program.listOfAllLessons.Find((candidate) => {
return candidate.plainTextName == selectedItem.Text //abbrev. on purpose
});
However I think it is undisputed that that is just horrible code, on more than one level.
Basically:
I would wish for listViewItem to have an
obj underlyingObject;
field that allows for easy access to the object represented by the listViewItem.
Is there a functionality that allows for this?
You could use the Tag property to store the associated object when creating the ListViewItem. As Tag is of type object you'd need to cast it appropriately when you read from it.
I can't seem to find an answer to this, maybe I'm not using the correct terminology.
I have a ListView that is editable, I want it so that if a user clicks on Edit and then Update, that the field is updated with the value from another textbox, not the field they are editing.
The reason for this is that I have a Colour Picker that alters the value of a textbox, when they click Update I want this value to be the updated value.
I guess I utilise the ItemUpdating event, but I don't have much in the way of code because I'm pretty lost. I have this so far:
protected void ListView2ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
var selectedItem = ListView2.Items[ListView2.EditIndex];
// I have no idea what to put here
something = ColourChosen.Value;
}
Here is an image that I hope will make what I'm trying to do a little more understandable:
If any one could point me in the right direction of any examples, that would be much appreciated.
Although this doesn't answer my initial question this does what I want to happen.
What I should be doing is altering the database that ListView is attached to.
I use this code:
protected void ListView2ItemUpdating(object sender, ListViewUpdateEventArgs e)
{
using (var myEntities = new i96X_utilEntities())
{
var myPlotColour = (from plotC in myEntities.PlotColours
where plotC.ID == selectedID
select plotC).Single();
myPlotColour.PlotColour1 = ColourChosen.Value;
myEntities.SaveChanges();
}
}
So, even though I have no idea how to intercept a field being updated in a ListView, in this example I don't need to.
I've built a form that has a listbox on the left side, and a bunch of text fields on the right for each field in the data source.
When the user clicks on an entry on the left it moves to that record so they can modify the fields on the right. All works fine up to this point.
The problem is that each user has a unique ID number and once they start typing in the record fields I want to populate a hidden field with their ID number so when they save, I know who touched that record.
I cannot find a suitable event to handle this method. I am not using a datagrid, I simply dragged members from the data sources window onto the form accordingly. CurrentChanged and CurrentItemChanged fire off when switching between items on the listbox so these don't reflect the behavior I need.
Any thoughts?
I feel this is a somewhat ugly answer, but it gets the job done without major any major effort. Once everything has been validated and the binding source EndEdit function has been called, you may check the DataSet for changed rows.
Before_Update handles this logic and looks at each row if changes have been made, making the necessary modifications to columns before calling UpdateAll.
Checking for Changed Rows -
http://msdn.microsoft.com/en-US/library/czb9z269%28v=VS.80%29.aspx
// Save event
private void clientBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.clientBindingSource.EndEdit();
Before_Update();
this.tableAdapterManager.UpdateAll(this.dP_TestDataSet);
}
// Place logic in here to modify records if they are changed
private void Before_Update()
{
if (dP_TestDataSet.HasChanges())
{
for (int tRow = 0; tRow < dP_TestDataSet.Tables["Client"].Rows.Count; tRow++)
{
// Modification Logic
if (dP_TestDataSet.Tables["Client"].Rows[tRow].RowState == DataRowState.Modified)
{
dP_TestDataSet.Tables["Client"].Rows[tRow]["userID"] = Program.SYSNG.UserID;
}
// Addition Logic
if (dP_TestDataSet.Tables["Client"].Rows[tRow].RowState == DataRowState.Added)
{
// Addition Logic
// ...
}
// Other RowStates such as Deleted, Detatched or Unchanged work here too
}
}
}
This successfully solves my problem though I am hoping someone comes along to trump this answer. I feel that I am doing extra work that the framework has hidden somewhere under the sheets on me and hope someone can provide me insight to this functionality.
I have a simple form with list as a data source, a binding source bound to the list, and a combo box bound to the binding source with some fields editing whatever the bindingSource.Current is. What I would like to do is if a bool is set pop up a dialog asking if they want to save changes before they change items. If they say no I want to call CancelEdit() if yes I want to keep them on the current item so they can click the save button. How do I do this?
The second part of my question is because my underlining data source is a List<View> will CancelEdit() even do anything? (View is just a class with string Name and a List<CustomColumn>
Edit:
Let me elaborate on what I am doing to maybe help explain what I am doing.
I have a list of View, these elsewhere in the program will be enumerated to generate a DataGridView. What this menu is for is adding new "Views" and changing the order of the columns in the view (it never actually edits the the CustomColumn just adding items and changing the order of the list<CustomColumn>). What I want to happen is if someone presses cancel or changes to a new view by using the combo box without saving it will undo any changes they made to the List<CustomColumn>
If I infer your question correctly, then the answer is not one that you're going to like; the ComboBox has no mechanism for cancelling a change of selection. I wish it did, as I have come across this issue time and time again. This is how i'd work around the limitation:
bool ignoreEvent = false;
object lastSelectedItem = null;
void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
if (ignoreEvent) return;
if (CheckForChanges()) {
if (MessageBox.Show("Do you want to save changes?", "Save changes", MessageBoxButtons.YesNo) == DialogResult.Yes) {
ignoreEvent = true;
comboBox1.SelectedItem = lastSelectedItem;
ignoreEvent = false;
}
else {
// call CancelEdit() here
}
}
lastSelectedItem = comboBox1.SelectedItem;
}
Basically, the above code offers the means to revert the ComboBox to its previous selected value, without calling any event handler code in the process. Users will briefly see their item selection change, then snap back if they answer 'No' on the popup.
Also, you're correct in your assertion that CancelEdit() will essentially do nothing - the generic List collection does not support change detection. You may wish to use a DataTable or an ObservableCollection, both of which support change detection.
In my app, I have a group of 3d objects and they're exposed to the user through a TreeView. When a user selects an item in the TreeView, an SelectedItemChanged event is fired, the corresponding 3d object is set to be selected and is highlighted in the 3d render window. This works fine.
What I'm having trouble with is the reverse. In a section of my code, I programatically set the selected 3d object in the scene. I want to reflect the currently selected object in the TreeView, so I run through the items until I find the corresponding one. But once I get to it, I can't find a way to make the item appear selected without having SelectedItemChanged being called, which is not what I want.
Is there a way to do this?
Thanks!
I take it you want to suppress the code in your event-handler? If so, a common way of doing this is with a boolean flag (or sometimes an int counter):
bool updatingSelected;
void SomeHandler(object sender, EventArgs args) { // or whatever
if(updatingSelected) return;
//...
}
void SomeCode() {
bool oldFlag = updatingSelected;
updatingSelected = true;
try {
// update the selected item
} finally {
updatingSelected = oldFlag;
}
}
Would it be appropriate to remove the TreeView's SelectedItemChanged event handler temporarily, and re-add it once you've performed the necessary operations? I haven't tried it myself, but it's the only other thing I can think of (Marc Gravell beat me to my original answer - I've done THAT before ;) ).
Good luck!