Dynamic indentation in devexpress aspxgridview - devexpress

Are anyone aware of any method to achieve indentation in the ASPXGridView (we are running the 10.x version currently available)
What we got
What we'd like to achieve
Some information about the code-behind.
The grid is populated by an ObjectDataSource and the indentation is stored in a property alongside with the other data. In example the BMI row will have 0 indentation while the GENDER will have 1, and MAN will have 2. Etc...
The indentation is calculated runtime since relations might change.
public void GetItemsRecursive(int? parentId, int level)
{
List<qstFeedbackLine> q;
if (parentId == 0)
q = _db.qstFeedbackLines.Where(x => x.ParentId == null).ToList();
else
q = _db.qstFeedbackLines.Where(x => x.ParentId == parentId).ToList();
foreach (var item in q)
{
// Store the indent
item.Indent = level;
// Add item to List
_items.Add(item);
level++;
// ...and get the children of the current id
GetItemsRecursive(item.FeedBackLineId, level);
}
}
Any advice out there?
Thanks!

Ended up using the ASPxTreeList component instead!
http://demos.devexpress.com/ASPxTreeListDemos/

Related

XtraGrid set selection on match datamember

We want to set the selection on a XtraGrid based on a List collection from the same type as the datamember of an XtraGrid.
The way we do it now is to iterate the gridview rows.
private void SetSelectedRowsInternal(IList<StrongType> collecshung)
{
grdvSomeGrid.ClearSelection();
grdvSomeGrid.BeginSelection();
for (int i = 0;i < grdvSomeGrid.RowCount;i++)
{
StrongType _strongTyped = ((StrongType)grdvSomeGrid.GetRow(i));
if (collecshung.Where(x => x.Id == _strongTyped.Id).Count() == 1)
grdvSomeGrid.SelectRow(i);
}
grdvSomeGrid.EndSelection();
}
Is there a better way to do this?
It depends on how you fill your grid ... You can directly iterate on the BindingList for instance (using LINQ). But if you find that it is taking more time than needed, then it should be because LINQ functions can be hit more than 1 million time even for a small amount of data.
I recommend you to use a dictionary instead of a LINQed collection.

How to simply delete row in QFormLayout programatically

I have this code:
myEdit = QLineEdit()
myQFormLayout.addRow("myLabelText", myEdit)
Now I have to remove the row by reference to myEdit only:
myQformLayout.removeRow(myEdit)
But there is no API for that. I can use .takeAt(), but how can I get the argument? How do I find the label index, or the index of myEdit?
You can just schedule the widget and its label (if it has one) for deletion, and let the form adjust itself accordingly. The label for the widget can be retrieved using labelForField.
Python Qt code:
label = myQformLayout.labelForField(myEdit)
if label is not None:
label.deleteLater()
myEdit.deleteLater()
my solution...
in header file:
QPointer<QFormLayout> propertiesLayout;
in cpp file:
// Remove existing info before re-populating.
while ( propertiesLayout->count() != 0) // Check this first as warning issued if no items when calling takeAt(0).
{
QLayoutItem *forDeletion = propertiesLayout->takeAt(0);
delete forDeletion->widget();
delete forDeletion;
}
This is actually a very good point... there is no explicit reverse function for addRow().
To remove a row you can do the following:
QLineEdit *myEdit;
int row;
ItemRole role;
//find the row
myQFormLayout->getWidgetPosition( myEdit, &row, &role);
//stop if not found
if(row == -1) return;
ItemRole otheritemrole;
if( role == QFormLayout::FieldRole){
otheritemrole = QFormLayout::LabelRole;
}
else if( role == QFormLayout::LabelRole){
otheritemrole = QFormLayout::FieldRole;
}
//get the item corresponding to the widget. this need to be freed
QLayoutItem* editItem = myQFormLayout->itemAt ( int row, role );
QLayoutItem* otherItem = 0;
//get the item corresponding to the other item. this need to be freed too
//only valid if the widget doesn't span the whole row
if( role != QFormLayout::SpanningRole){
otherItem = myQFormLayout->itemAt( int row, role );
}
//remove the item from the layout
myQFormLayout->removeItem(editItem);
delete editItem;
//eventually remove the other item
if( role != QFormLayout::SpanningRole){
myQFormLayout->removeItem(otherItem);
delete otherItem
}
Note that I retrieve all the items before removing them. That's because I don't know if their role will change when an item is removed. This behavior is not specified so I am
playing safe. In qt designer, when you remove an item from a form, the other item on
the row take all the space (which means his role changes...).
Maybe there is a function somewhere and not only I reinvented the wheel but I made a broken one...

Filtering a Backbone.js collection by index

I have Backbone.js collection that holds (for example) 30 items.
I want to pass to my template filtered collection consist of every 3rd item in the original collection.
Does anyone know how it can be done elegantly? CoffeeScript code is preferred.
Assuming here that originalCollection is your existing collection
var newCollection = new Backbone.Collection();
for (var i = 0, l = originalCollection.length; i < l; i++) {
if (i % 3 === 0) { newCollection.add(originalCollection.models[i]); }
}
This code works by looping through each existing model, and only adding the model the new collection if it's index is a multiple of 3.
You could make this a little nicer, by using the underscore each method exposed by Underscore.js in Backbone Collections:
var newCollection = new Backbone.Collection();
originalCollection.each(function (model, index) {
if (index % 3 === 0) { newCollection.add(model); }
});
Converting the above to CoffeeScript results in:
newCollection = new Backbone.Collection()
originalCollection.each (model, index) ->
newCollection.add model if index % 3 is 0
Backbone collection have some useful Underscore methods mixed-in. You can use filter to get an array of models that you can pass to the template:
filteredModels = collection.filter (model, i) -> i % 3 == 0
Alternatively, you can use an array comprehension; though I think this is less readable...
filteredModels = (model for model, i in collection.models when i % 3 == 0)
If you really need a Backbone.Collection in your template, you can create a new one with those filtered models:
filteredCollection = new Backbone.Collection filteredModels
Here is a working jsfiddle example.

Regarding to retrieve values inside the array

Hi
I am creating online quiz in asp.net c#. For that i have one form that displays testlist in dropdownlist & start button. After clicking 2nd form appears, 2nd form shows one label for question, radiobuttonlist for answers ,next & checkbox for review. I am creating array of random question ids in start button click event of the 1stform. when i click next button in 2nd form then next random question appears, i want array of questions those are checked for review. I used code for arrays of values ( eg.10101) 1 for true & 0 for false as follows but i want array of that question ids those are checked:
int[] a = (int[])Session["values"];//this is array of random question ids created in 1st form
int g;
if (chkmark.Checked == true)
{
g = 1;
}
else
{
g = 0;
}
int[] chkarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
int[] temp1 = (int[])Session["arrofchk"];
int k, no;
if (temp1 == null)
no = 0;
else
no = temp.Length;
for (k = 0; k < no; k++)
{
chkarray[k] = temp1[k];
}
chkarray[j] = g;
Personally, i would use a Dictionary<int, bool> for this.
In the key of the dictionary, you can store the random Question ID, in the value of the pair, you can store the checked item state. It might take you more work now to refactor it, but I believe it will save you a lot of time in the end when you want to do more actions on your quiz items.
Using a dictionary - or at least a well chosen collection, I think it will be easier to get the right data back.
For your example, it can work only if the positions of both arrays are the same.
Dictionary<int, bool> quizAnswers = new Dictionary<int, bool>(); // <questionID, checked>
// Fill dictionary with questions and answers
for(int i=0;i<a.length;i++)
{
if(temp1.length > i) // Make sure we don't get an IndexOutOfBoundsException
{
quizAnswers.Add(a[i], temp1[i] == 1);
}
}
// Get Answered question in array ( LINQ )
int[] checkedAnswers = (from KeyValuePair<int, bool> pair in quizAnswers
where pair.Value == true
select pair.Key).ToArray<int>();
The reason I am using a Dictionary here, is because I personally think it's neater than having two separate arrays.
I believe you should implement a Dictionary in your quiz, in stead of those arrays. What if the array indexes don't match, or you want to dynamically add a question to a fixed size array, etc..
It's something to take into consideration. Hope I could help you out.

LINQ sorting, doesn't work

I have a LINQ query like this:
from i in _db.Items.OfType<Medium>()
from m in i.Modules
from p in m.Pages
where i != null && i.Type == 1 && i.Published == true && p.PageId == 2
select p
I use the query like this because I have strongly typed view (ASP.NET MVC).
I need to have items sorted by the i.Sort property. orderby i.Sort and i.OrderBy(it => it.Sort) doesn't work. How can I fix this?
When sorting with Linq you usually give OrderBy a property, and eventually an IComparer, not a sorting function. For example:
class Person {
public int Age {get; set;}
}
public static void Main() {
var ps = new List<Person>();
ps.Add(new Person{Age = 1});
ps.Add(new Person{Age = 5});
ps.Add(new Person{Age = 3});
var sorted = ps.OrderBy(p => p.Age);
foreach(p in sorted) {
Console.WriteLine(p.Age);
}
}
Here Linq will know how to correctly sort integers.
Without giving more context (such as what exactly is i.Sort, what is its purpose, what do you want to do with it), it would be difficult to be more specific to your problem.
However, I'm pretty sure you are misunderstanding OrderBy: you should give it a lambda expression that identifies a property of the objects contained in your sequence, and then Linq will sort your sequence according to the usual order of the type of that property (or according to another order you define for that type, by using IComparer).
Let's say your Pages include page-numbers among their properties. Let's pretend this property is called "pagenumber". You would then add the following 'orderby' line between the 'where' and 'select' lines.
// (snip...)
where i != null && i.Type == 1 && i.Published == true && p.PageId == 2
orderby p.pagenumber
select p
Or maybe you don't have page numbers, but only page titles. You would do nearly the same thing:
where i != null && i.Type == 1 && i.Published == true && p.PageId == 2
orderby p.title
select p
Just from reading your code, I can't tell what criteria should be used for sorting. You need some kind of ordered element, an id number, a page number, or some text can be alphabetized.
from i in _db.Items.OfType<Medium>().OrderBy(x => x.Sort)
...

Resources