write linq query sitemapnode - c#

I want to write query smn.ParentNode.ChildNodes. If ShowInNavigation value false, I don't want to show. Telerik Site map node has this att. Ho to do this?
using System;
using System.Web;
using Telerik.Sitefinity.Web;
using System.Linq;
using System.Data;
public partial class CustomTemplate_Navigation : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
SiteMapNode smn = SiteMapBase.GetCurrentProvider().CurrentNode;
while (smn.ParentNode != null)
{
if (smn.ParentNode.ParentNode == SiteMap.RootNode)
{
siteMapControl_verticaltree.DataSource = smn.ParentNode.ChildNodes;/*this line will be write query*/
siteMapControl_verticaltree.DataBind();
break;
}
smn = smn.ParentNode;
}
}
}

something like this:
smn.ParentNode.ChildNodes.AsQueryable().Where(x => x.ShowInNavigation).ToList();

You could do somthing like this: (you should not only Linqify, but you need a cast also)
(I used this in a .NET MVC4 project)
SiteMapNodeCollection coll = SiteMap.RootNode.ChildNodes;
IEnumerable<SiteMapNode> nodes = coll.Cast<SiteMapNode>();
var query = from node in nodes where Boolean.Parse(node["ShowInNavigation"]) == true select node;

Related

Sharepoint 2010 - webpart treeview is not working

Hi I am using sharepoint 2010 and am creating a tree view in a webpart to display items from a document library. This code isn't working for me, its displaying everything in the same web...
I would like to be able to specify which document library to use.
Also it puts in duplicate nodes in, so if I go to editpage, it adds a duplicate, if I leave edit mode it adds another duplicate.
Can anyone help?
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Web;
using System.IO;
namespace VisualWebPartProject1.VisualWebPart1
{
public partial class VisualWebPart1UserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
SPWeb thisWeb = null;
TreeNode node;
using (thisWeb = SPContext.Current.Web)
{
//Add the Web's title as the display text for the tree node, and add the URL as the NavigateUri.
node = new TreeNode(thisWeb.Title, null, null, thisWeb.Url, "_self");
//The Visual Web Part has a treeview control called siteStructure.
siteStructure.Nodes.Add(node);
//Get a reference to the current node, so child nodes can be added in the correct position.
TreeNode parentNode = node;
//Iterate through the Lists collection of the Web.
/*
foreach (SPListItem item in myList.Items)
{
SPFieldUrlValue data = item["Url"] as SPFieldUrlValue;
// now you have data.Description, data.Url
node = new TreeNode(Path.GetFileName(data.Url), null, null, data.Url, "_self");
parentNode.ChildNodes.Add(node);
}
*/
foreach (SPList list in thisWeb.Lists)
{
if (!list.Hidden)
{
node = new TreeNode(list.Title, null, null, list.DefaultViewUrl, "_self");
parentNode.ChildNodes.Add(node);
}
}
foreach (SPWeb childWeb in thisWeb.Webs)
{
//Call our own helper function for adding each child Web to the tree.
addWebs(childWeb, parentNode);
childWeb.Dispose();
}
siteStructure.CollapseAll();
}
}
void addWebs(SPWeb web, TreeNode parentNode)
{
TreeNode node;
node = new TreeNode(web.Title, null, null, web.Url, "_self");
parentNode.ChildNodes.Add(node);
parentNode = node;
foreach (SPList list in web.Lists)
{
if (!list.Hidden)
{
node = new TreeNode(list.Title, null, null, list.DefaultViewUrl, "_self");
parentNode.ChildNodes.Add(node);
}
}
foreach (SPWeb childWeb in web.Webs)
{
//Call the addWebs() function from itself (i.e. recursively)
//to add all child Webs until there are no more to add.
addWebs(childWeb, parentNode);
childWeb.Dispose();
}
}
}
}
Try adding this before your using statement:
If(node.Nodes.Count == 0) { // The rest of your code here }
Add WebProperties to your WebPart to be able to configure for example the Library which you would like to use instead a hardcoded one. In this Property you could specify the Lists Name and read it to load this list.
Also to avoid multiple inserts on edit, etc. please add your code inside the Page_Load Event inside
if (!Page.IsPostBack)
{
Your code goes here...
}
This avoids the execution of your code everytime you load or even postback the page and this causes that you add each time a new node to your tree.

Applications changing the language at runtime

I have read the tutorials about how to make a multilingual program in .Net, and it works well, but here I need an idea to make all the things at run-time easier.
At run-time when the user click on the language. I change the culture to the proper language chosen for example:
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
and then calling a function which set the Text for the layout of my form:
private System.Resources.ResourceManager rm;
fileToolStripMenuItem1.Text = rm.GetString("fileToolStripMenuItem1.Text");
settingsToolStripMenuItem.Text = rm.GetString("settingsToolStripMenuItem.Text");
As it seems the look-up table which has been built by .Net when I set the text for each component of my program is equals to the property which should be set into it. In other word, the "fileToolStripMenuItem1.Text" is passing to the GetString() function and the result should be set to fileToolStripMenuItem1.Text, so I don't know how can I do it or even with which tool it is possible to iterate on every property of the rm and then by reflection or something else assign the value of the key to the key. That is to say, suppose "fileToolStripMenuItem1.Text" is the key in the lookup table and the value is "A" so how can I do this: Assigning the value of "fileToolStripMenuItem1.Text" which is "A" to fileToolStripMenuItem1.Text
I've written some test winforms app and try it and can change controls Text property dynamicly fine. You can extend this solution if need.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace ConsoleApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//main logic of switching language of UI
void ChangeCulture_Handler(CultureInfo culture)
{
//getting relative path of resource file for specific culture
var resourcePath = GetLocalizedResourceFile(culture);
//initialize new reader of resource file
var reader = new ResXResourceReader(resourcePath);
//getting enumerator
var resourceEnumerator = reader.GetEnumerator();
//enumerate each record in resource file
while (resourceEnumerator.MoveNext())
{
string resKey = Convert.ToString(resourceEnumerator.Key);
//we can add here some check if need
//(for example if in resource file exists not only controls resources with format <Control Name>.<Property>
//if( resKey.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries).Length == 2)
string resValue = Convert.ToString(resourceEnumerator.Value);
//actually update property
UpdateControl(resKey, resValue);
}
}
//main logic of updating property of one control
private void UpdateControl(string resKey, string resValue)
{
//we suppose that format of keys in resource file is <Control Name>.<Property>
var strs = resKey.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
var controlName = strs[0];
var controlProp = strs[1];
//find control of form by its name
var controls = this.Controls.Find(controlName, true);
if (controls.Length > 0)
{
//select first control
var control = controls[0];
//getting type of it
var t = control.GetType();
//getting property
var props = t.GetProperty(controlProp);
if (props != null)
{
//setting localized value to property
props.SetValue(control, resValue, null);
}
}
}
//build resource file path
string GetLocalizedResourceFile(CultureInfo ci)
{
string cultureCode = ci.TwoLetterISOLanguageName;
//for english language is default, so we don't have a need to add "en" part in path
return cultureCode != "en" ? string.Format("Resource1.{0}.resx", cultureCode) : "Resource1.resx";
}
private void button1_Click(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("es-MX");
ChangeCulture_Handler(Thread.CurrentThread.CurrentCulture);
}
private void button2_Click(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
ChangeCulture_Handler(Thread.CurrentThread.CurrentCulture);
}
}
}
Resource for english (Resource1.resx)
button1.Text Change language to es
button2.Text Change language to en
label1.Text label1
label2.Text label2
Resource for spanish (Resource1.es.resx)
button1.Text cambiar el idioma to es
button2.Text cambiar el idioma to en
label1.Text lalble1
label2.Text lalble2

Saving Xml to a Document C#

Unlike what I've been able to find on here I wand to maintain syntax within my xml document, and serialization doesn't touch on that. I want to be able to add another "task" tag to the xml document...Loading the information isn't a problem, I've had to deal with that before... but this is.
Main Program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;
namespace ToDoList
{
public partial class Form1 : Form
{
string title; //the variable for the title textbox value to be stored in
string details; //the variable for the details textbox value to be stored in
string itemstr; //the variable for title and details to be merged in
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
optionsbtn.Text = "Options"; //make the options button's text options
var items = ToDochkbox.Items; //create a private "var" items symbolizing the Checkbox's items array
XDocument xmlDoc = XDocument.Load("tasksdoc.xml"); //load the xml document (in bin or release)
var q = from c in xmlDoc.Descendants("root") //go "within" the <root> </root> tag in the file
select (string)c.Element("task"); //find the first <task></task> tag
foreach (string N in q) //now cycle through all the <task></task> tags and per cycle save them to string "N"
{
items.Add(N); //add the item to the checkbox list
}
}
public void addbtn_Click(object sender, EventArgs e)
{
var items = ToDochkbox.Items; //create a private "var" items symbolizing the Checkbox's items array
title = Addtb.Text; //set the title string to equal the title textbox's contents
details = detailstb.Text; //set the details string to equal the detail textbox's contents
itemstr = title +" - " + details; //set a variable to equal the title string, a - with spaces on each end, and then the details string
items.Add(itemstr); //add the variable itemstr (above) to the the checkbox list
}
private void optionsbtn_Click(object sender, EventArgs e)
{
new options().Show();//show the options form
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
new options().Show();//show the options form
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
}
public void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
optionsbtn.Text = "Options"; //make the options button's text options
var items = ToDochkbox.Items; //create a private "var" items symbolizing the Checkbox's items array
XDocument xmlDoc = XDocument.Load("tasksdoc.xml"); //load the xml document (in bin or release)
var q = from c in xmlDoc.Descendants("root") //go "within" the <root> </root> tag in the file
select (string)c.Element("task"); //find the first <task></task> tag
foreach (string N in q) //now cycle through all the <task></task> tags and per cycle save them to string "N"
{
items.Add(N); //add the item to the checkbox list
}
}
}
}
And My XML Document:
<root>
<task>First Task - Create a Task</task>
</root>
The class that you could use to serialize:
public class MyClass
{
[XmlElement("task")]
public List<string> Tasks { get; set; }
}
Placing the XmlElementAttribute on a collection type will cause each element to be serialized without being placed a node for the list.
Xml with XmlElementAttribute:
<root>
<task>First Task - Create a Task</task>
<task>SecondTask - Create a Task</task>
<task>ThirdTask - Create a Task</task>
</root>
Xml without XmlElementAttribute:
<root>
<Tasks>
<Task>First Task - Create a Task</Task>
<Task>SecondTask - Create a Task</Task>
<Task>ThirdTask - Create a Task</Task>
</Tasks>
</root>
I answered another question about serializing lists in a similar way a few days ago. Check out his question and then the answer, it might be what you are trying to do.

Howto add Ext.Net.ColumnModel to an existing Ext.Net.GridPanel programmatically?

I try to create a GridPanel programmatically using a LinqDataSource as shown in the examples.
So far I can see my empty GridPanel without any data inside cause my GridPanel is missing the ColumnModel used to show the data.
As I can't find the right method to add the ColumnModel to the GridPanel I need to ask you.
My Code which is used to create my GridPanel and everything is underneath.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace IntraNET_Prototype
{
public partial class MitarbeiterUndTelefonliste : System.Web.UI.Page
{
public LinqDataSource MitarbeiterDataSource = new LinqDataSource();
public Ext.Net.GridPanel MitarbeiterGridPanel = new Ext.Net.GridPanel();
public Ext.Net.Store MitarbeiterStore = new Ext.Net.Store();
public Ext.Net.JsonReader MitarbeiterJSONReader = new Ext.Net.JsonReader();
public Ext.Net.ColumnModel MitarbeiterColumnModel = new Ext.Net.ColumnModel();
public MitarbeiterUndTelefonliste()
{
}
protected void Page_Load(object sender, EventArgs e)
{
MitarbeiterDataSource.ID = "MitarbeiterDataSource";
MitarbeiterDataSource.ContextTypeName = "MitarbeiterlisteEntities";
MitarbeiterDataSource.TableName = "Mitarbeiterliste";
MitarbeiterGridPanel.ID = "MitarbeiterGridPanel";
MitarbeiterGridPanel.Title = "MitarbeiterListe";
MitarbeiterGridPanel.AutoWidth = true;
MitarbeiterGridPanel.Frame = true;
MitarbeiterGridPanel.Height = 570;
MitarbeiterStore.ID = "MitarbeiterStore";
MitarbeiterStore.DataSource = MitarbeiterDataSource;
MitarbeiterColumnModel.ID = "MitarbeiterColumnModel";
MitarbeiterColumnModel.Columns.Add(new Ext.Net.Column() { DataIndex = "primaerschluessel", Header = "Index", Width = 50 });
MitarbeiterJSONReader.Fields.Add(new Ext.Net.RecordField() { Name = "primaerschluessel" });
MitarbeiterGridPanel.Store.Add(MitarbeiterStore);
this.Form.Controls.Add(MitarbeiterGridPanel);
}
}
}
Thanks in advance for any help! I appreciate any suggestions, critics and any help!
You can't assign some column model to the grid. Because it's read-only property.
You have to use MitarbeiterGridPanel.ColumnModel.Columns.Add() instead of MitarbeiterColumnModel.Columns.Add()

C# in Visual Studio: How to display a list in a DataGridView? Getting weird stuff

Been a while and I've volunteered to teach myself Windows programming at my company. Started writing vbs scripts and suddenly realized how incredibly useful this programming thing is ;-)
Anyway, I'm a total newbie at C# AND Visual Studio, I kind of get how it works, you drag and drop interface pieces in the design side then wire them together in the back/program side.
I'm trying to write a program that will (ultimately) read in a (very specific kind of) csv file and give the user a friendlier way to edit and sort through it than Excel. Should be simple stuff, and I'm excited about it.
I started this morning and, with the help of the internet, got as far as reading in and parsing the CSV (which is actually a TSV, since they use tabs not commas but hey).
I've been trying to figure out the best way to display the information, and, for now at least, I'm using a DataGridView. But the data isn't displaying. Instead, I'm seeing a long grid of values with column headers of Length, LongLength, Rank, SyncRoot, IsReadOnly, IsFixedSize, and IsSynchronized.
I don't know what any of these mean or where they come from, and unfortunately I don't know how change them either. Maybe somebody can help?
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace readInCSV
{
public partial class readInCSV : Form
{
public readInCSV()
{
InitializeComponent();
}
public List<string[]> parseCSV(string path)
{
List<string[]> parsedData = new List<string[]>();
try
{
using (StreamReader readfile = new StreamReader(path))
{
string line;
string[] row;
while ((line = readfile.ReadLine()) != null)
{
row = line.Split('\t');
parsedData.Add(row);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return parsedData;
}
//PRIVATE METHODS FROM HERE ON DOWN
private void btnLoadIn_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult csvResult = openCSVDialog.ShowDialog();
if (csvResult == DialogResult.OK)
{
string file = openCSVDialog.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
}
catch (IOException)
{
}
}
dgView.Dock = DockStyle.Top;
dgView.EditMode = DataGridViewEditMode.EditOnEnter;
dgView.AutoGenerateColumns = true;
dgView.DataSource = parseCSV(openCSVDialog.FileName);
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void openCSVDialog_FileOk(object sender, CancelEventArgs e)
{
}
}
}
Thanks in advance!
What's happening here is that the DataGridView is trying to display all the information for each of the string arrays in your parsedData List.
When you set a DataGridView's DataSource as a List of objects, it attempts to interpret each of the objects as a row to display. parsedData is a List of string array objects, so the grid is showing you all the displayable properties for an array object.
What we can do is parse each TSV row into a custom class (call it TsvRow) which has all the relevant data exposed. The TsvRow objects are then placed in a List and passed to the DataGridView. An example of this approach is explained in this article.
For example:
public class TsvRow
{
// Properties to hold column data
public string Column1 { get; set; }
public string Column2 { get; set; }
}
...
public List<TsvRow> parseCSV(string path)
{
List<TsvRow> parsedData = new List<TsvRow>();
try
{
using (StreamReader readfile = new StreamReader(path))
{
string line;
string[] row;
while ((line = readfile.ReadLine()) != null)
{
row = line.Split('\t');
// Here we assume we know the order of the columns in the TSV
// And we populate the object
TsvRow tsvRow = new TsvRow();
tsvRow.Column1 = row[0];
tsvRow.Column2 = row[1];
parsedData.Add(myObject);
}
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
return parsedData;
}
Since all your column data is exposed as properties (i.e. "Column1" and "Column2"), they should be reflected in the DataGridView automatically.
Hope that helps! Please let me know if this needs clarification.
The DataGridView tries to display the Properties of your string-Array. You should set AutoGenerateColumns = false and create the columns by yourself.
Would the first line of the CSV/TSV contain the column names? Is so, you shouldn't pass them as DataSource.
dgView.AutoGenerateColumns = false;
foreach(string name in columnNames)
{
dgView.Columns.Add(name, name);
}

Categories

Resources