Populating RadMenu Dynamically from Code Behind - c#

I am trying to dynamically populate a Telerik Radmenu control in my code behind. I'm having a really hard time with it. I need to be able to bind my categories to my root elements and attributes to the child elements. I really am lost on this. If even someone has a suggestion of a better way to do this, even if it's with a different type of menu I would be very happy to try it out. Thanks in advance.
**EDIT my code has changed.
protected void createFilter(int categoryid)
{
// check cateogyrid
//get list of proudct id
List<int> productIds = new List<int>();
DataRow[] productRow = CategoriesProductsData.Tables["Products"].Select("Category_ID = " + 573);
productIds = productRow.Select(p => int.Parse(p["Product_ID"].ToString())).ToList();
//get attributes
ITCProductService pService = new TCProductServiceClient();
var productTuples = (pService.GetProductsAttributes(productIds));
List<Tuple<int, CustomAttribute>> customAttributes = new List<Tuple<int, CustomAttribute>>();
foreach (var productTuple in productTuples)
{
foreach (var attributeTuple in productTuple.m_Item2)
{
var customAttribute = new Tuple<int, CustomAttribute>(productTuple.m_Item1, new CustomAttribute(attributeTuple));
customAttributes.Add(customAttribute);
}
}
List<CustomAttributeCategory> categories = new List<CustomAttributeCategory>();
var categoryTuples = customAttributes.Select(a => a.Item2).Select(a => a.Attribute.Category).Distinct();
foreach (var categoryTuple in categoryTuples)
{
var category = new CustomAttributeCategory(categoryTuple);
var attributeByCategory = customAttributes.Select(a => a.Item2).Where(b => b.Attribute.CategoryId == categoryTuple.AttributeCategoryId).Distinct();
foreach (var attributeTuple in attributeByCategory)
{
var attribute = new CustomAttribute(attributeTuple.Attribute);
var attributeProductIds = customAttributes.Where(a => a.Item2.Attribute.AttributeId == attributeTuple.Attribute.AttributeId).Select(a => a.Item1).ToList();
attribute.ProductIds = attributeProductIds;
category.Attributes.Add(attribute);
}
categories.Add(category);
foreach (var cat in categories)
{
var itemCategory = new RadMenuItem(cat.Category.Name.ToString());
handsetMenu.Items.Add(itemCategory);
var itemAttribute = new RadMenuItem(cat.Attributes.ToString());
handsetMenu.Items.Add(itemAttribute);
}
}
}
<%--RAD MENU--%>
<telerik:RadMenu ID="handsetMenu" runat="server" ShowToggleHandle="true">
</telerik:RadMenu>

I don't think ItemDataBound is the correct place to add child items.
Do you want to add the same child items under each of the root menu items?
Try doing it in the DataBound event (which fires after all itemDataBound events have completed) by iterating all RadMenu items.

Related

GROUP BY to List<> with Linq

I'm new to using Linq so I don't understand some things or its syntax. I want to group a list and then loop through it with foreach, like my logic below. Obviously my logic doesn't work.
My code:
var final = finalv.Union(finalc);
final = final.GroupBy(x => x.Clave);
foreach (var articulo in final)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articulo.ArtID;
articulo2.Clave = articulo.Clave;
articulo2.ClaveAlterna = articulo.ClaveAlterna;
lista.Add(articulo2);
}
First, such usage is syntactically consistent with this overloaded method of GroupBy: GroupBy<TSource,TKey>(IEnumerable<TSource>, Func<TSource,TKey>), and it will return a IEnumerable<IGrouping<TKey,TSource>> variable.
That means, if you run final.GroupBy(x => x.Clave), let's assume he returns finalWithGrouped, then finalWithGrouped.Key is the key and finalWithGrouped.ToList() is a collection of all variables with the same key(at here, it is with the same Clave).
And for your code, try this:
var final = finalv.Union(finalc);
var finalWithGrouped = final.GroupBy(x => x.Clave);
foreach (var articulosWithSameClavePair in finalWithGrouped)
{
var clave = articulosWithSameClavePair.Key;
var articulos = articulosWithSameClavePair.ToList();
foreach(var articulo in articulos)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articulo.ArtID;
articulo2.Clave = articulo.Clave;
articulo2.ClaveAlterna = articulo.ClaveAlterna;
lista.Add(articulo2);
}
}
I suggest you read some examples of using GroupBy.
When you group a list, it will return a key and groued list and you are trying reach a single property of a list.
When you group an data, you can convert it to dictionary, It is not nessesary but better way for me. You can try this code:
var final = finalv.Union(finalc);
final = final.GroupBy(x => x.Clave).ToDictionary(s=> s.Key, s=> s.ToList();
foreach (var articulo in final)
{
foreach (var articuloItem in articulo.value)
{
Articulo articulo2 = new Articulo();
articulo2.ArtID = articuloItem.ArtID;
articulo2.Clave = articuloItem.Clave;
articulo2.ClaveAlterna = articuloItem.ClaveAlterna;
lista.Add(articulo2);
}
}

How can I create a list inside a list with a foreach in c# ?

In other words I need all the elements of list "Categories" to be the "Parent" and elements of list "commodities" be the children.
Example
public string GetCommodities()
{
List<dynamic> categories = new List<dynamic>();
List<dynamic> commodities = new List<dynamic>();
foreach (var comcat in QuickQuoteRepo.CommodityCategories.All().OrderBy(o => o.Order))
{
categories.Add(new
{
comcat.Category,
});
foreach (var com in comcat.Commodities.OrderBy(o => o.Name))
{
commodities.Add(new
{
com.Name,
});
}
}
var response = new JavaScriptSerializer().Serialize(commodities);
return response;
}
And see if it's possible to all commodities names inside each category, within this foreach.
I tried adding a dynamic list such as:
dynamic listOfElements = new { CAT = categories, COMM = commodities };
But it does't return elemnts as parents or dependency of categories. Is the same as adding
commodities.Add(new
{
comcat.Category,
com.Name,
});
public string GetCommodities()
{
List<dynamic> categoryCommodityList = new List<dynamic>();
foreach (var comcat in QuickQuoteRepo.CommodityCategories.All().OrderBy(o => o.Order))
{
var allCommodities = comcat.Commodities.OrderBy(o => o.Name).Select(com => com.Name).ToList();
categoryCommodityList.Add(new { Catagory = comcat.Category, Items = allCommodities } );
}
return new JavaScriptSerializer().Serialize(categoryCommodityList);
}
You class structure does not support parent-child relationships. I mean, if what you want is that each Category holds a list of commodities, then you would need something like this:
var result = from c in comcat
select new { Category = c, Commoddities = c.Commoddities};
This will return a hierarchy of Categories including all Commodities underneath it.
If you are just receiving a flat data set, then you need something like this:
var result = from c in comcat
select new { Category = c,
Commoddities = c.Where(x=>x.Category.Name == c.Name).Select(x=>x.Commodity) };
Hopefully you get the idea...

Gridview (collection view source) does not get the source from a awaitable function which calls an API in C# UWP

here is the code for my CollectionViewSource
<CollectionViewSource x:Name="GridviewCVS" IsSourceGrouped="True" />
And code behind for the same is
ObservableCollection<GroupInfoList> list = new ObservableCollection<GroupInfoList>();
list = await getMenuGrouped();
GridviewCVS.Source = list;
when i run this without await and synchronously i get the values in my gridview, but when i try to run it asynchrounously and get the data from HTTPClient it doesnt show any values, added breakpoints, it shows data in that but doesnt show it in gridview.
public async static Task<ObservableCollection<MenuModel>> GetMenu()
{
ObservableCollection<MenuModel> _menu = new ObservableCollection<MenuModel>();
MenuVM viewModel = new MenuVM();
List<MenuModel> AllMenuItems = await viewModel.GetAllMenuItems();
foreach (var item in AllMenuItems)
{
_menu.Add(item);
}
return _menu;
}
public async static Task<ObservableCollection<GroupInfoList>> getMenuGrouped()
{
ObservableCollection<GroupInfoList> groups = new ObservableCollection<GroupInfoList>();
ObservableCollection<MenuModel> _menu = new ObservableCollection<MenuModel>();
_menu = await GetMenu();
var query = from item in _menu
group item by item.CategoryName into g
orderby g.Key
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{
GroupInfoList info = new GroupInfoList();
info.Key = g.GroupName;
foreach (var item in g.Items)
{
info.Add(item);
}
groups.Add(info);
}
return groups;
}
I tried other way in trying to attach the data, the CollectionViewSource was in the xaml and the items were coming properly but not getting assigned to the view so tried the below and removed the binding from the UI.
CollectionViewSource vs = new CollectionViewSource();
vs.IsSourceGrouped = true;
vs.Source = staticData.GridViewData;
MenuGridView.ItemsSource = vs.View;
Basically did set the collection view source from c# code instead of binding, but still want to know why the above didnt work.

querying existing ListView items with LINQ

The ListView I have populates through these loops resulting in four columns being filled
// Create a ResXResourceReader
ResXResourceReader rdr0 = new ResXResourceReader(textPath1.Text + ".resx");
ResXResourceReader rdr1 = new ResXResourceReader(textPath1.Text + ".es.resx");
ResXResourceReader rdr2 = new ResXResourceReader(textPath1.Text + ".fr.resx");
foreach (DictionaryEntry d in rdr0)
{
TransResource x = new TransResource();
x.id = d.Key.ToString();
x.en = d.Value.ToString();
resources.Add(x.id, x);
}
foreach (DictionaryEntry d in rdr1)
{
TransResource x = resources[d.Key.ToString()];
x.fr = d.Value.ToString();
}
foreach (DictionaryEntry d in rdr2)
{
TransResource x = resources[d.Key.ToString()];
x.es = d.Value.ToString();
}
foreach (TransResource x in resources.Values)
{
string[] row = { x.id, x.en, x.fr, x.es };
var listViewItem = new ListViewItem(row);
listResx.Items.Add(listViewItem);
}
What I want to do is query all of the results in this ListView against what is entered in textboxQuery. If any field in the entire listview contains the string from textboxQuery I want it to be displayed in a new listview (lets say listviewQueryresult). I've had many failed attempts at this but I know it is possible through LINQ.
Because ListView.Items implements IEnumerable, but does not implement IEnumerable<T> you have to cast it to IEnumerable<ListViewItem> first, to query it using LINQ to Objects:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => YourPredicate(x));
If any field in the entire listview contains the string from
textboxQuery I want it to then be displayed in a new listview (lets
say listviewQueryresult)
For that, the predicate would be just:
var results = listResx.Items.Cast<ListViewItem>()
.Where(x => x.Text.Contains(textboxQuery));

WPF Treeview using linq to entities multiple relations

I don't know what I'm missing on this:
I have this relationship in my EDM- (can't load a picture yet)
Category_1__many RecipeCategory_many__1_Recipe
Basically every recipe has one or more categories and every category can have 0 or more recipes
Here's my code:
private void LoadData()
{
List<Category> Categories = new List<Category>();
List<Recipe> Recipes = new List<Recipe>();
var ctx = new MaWEntities();
var query = from x in ctx.Categories select x;
Categories = query.ToList<Category>();
foreach (Category c in Categories)
{
TreeViewItem TVP = new TreeViewItem() { Header = c.CategoryName.ToString() };
var qq = from xx in ctx.RecipeCategories.Where(o => o.CategoryId == c.CategoryId) select xx;
foreach (var rc in qq)
{
TreeViewItem TVC = new TreeViewItem() { Header = rc.Recipe.RecipeName.ToString() };
TVP.Items.Add(TVC);
//TVP.IsExpanded = true;
}
}
}
What I am trying to accomplish is a treeview whose parent nodes are the categoryname and child nodes are the recipe name. I know how drill into a relational table from a base table (Recipe to RecipeCategory) using Linq. There MUST also be a way to traverse again to the Category table too. I should also mention that even if the Category does not have any Recipes I still want to see the Category Name as a parent in the treeview.
I found that my problem in this scenario was not that my code wasn't working; rather that I neglected to ever add the treeview items to my treeview. Also, this addition needs to be done after the foreach loop. List Categories = new List();
List Recipes = new List();
var ctx = new MaWEntities();
var query = from x in ctx.Categories select x;
Categories = query.ToList<Category>();
foreach (Category c in Categories)
{
TreeViewItem TVP = new TreeViewItem() { Header = c.CategoryName.ToString() };
var query2 = from xx in ctx.RecipeCategories.Where(o => o.CategoryId == c.CategoryId) select xx;
foreach (var rc in query2)
{
TreeViewItem TVC = new TreeViewItem() { Header = rc.Recipe.RecipeName.ToString() };
TVP.Items.Add(TVC);
}
tvwRecipe.Items.Add(TVP);
}

Categories

Resources