How to maintain checkstate of items in Devexpress Virtual Treeview? - c#

I have a Treeview created in virtual mode which have 4 levels of nodes and at the page load the root element and first level elements are loaded and rest will be loaded based on dynamically using treeFolderList_VirtualModeCreateChildren event.
This is what I have so far
protected void treeFolderList_VirtualModeCreateChildren(object source, TreeViewVirtualModeCreateChildrenEventArgs e)
{
List<TreeViewVirtualNode> children = new List<TreeViewVirtualNode>();
if (e.NodeName == null)
{
AppendChildNode(children, "root", "All Domains", false);
}
else
{
if (e.NodeName.Contains("root"))
{
PopulateChildNodes(false, children);
}
else
{
if (!(e.NodeName.StartsWith("u_")))
{
PopulateUserChildNodes(false, children, GetDomainBase(e.NodeName), e.NodeName);
}
else
{
TreeViewVirtualNode tvNode = (TreeViewVirtualNode)treeFolderList.Nodes.FindByName(e.NodeName);
TreeViewVirtualNode tvNodeParent = (TreeViewVirtualNode)tvNode.Parent;
string tvParentNodeName = tvNodeParent.Name;
PopulateUserChildNodes(true, children, GetDomainBase(tvParentNodeName), e.NodeName);
}
}
}
e.Children = children;
}
This work as expected and it creates the children elements when expanding nodes respectively. My problem is I have check boxes for each node and I need to be able to save the Treeview in a way when I reload/redirect to the page it would reflect the nodes I have selected.
Is there a way to achieve this?

There are several ways to try to achieve this:
Configure ASPxTreeList.SettingsCookies element (probably the easiest solution), in particular the StoreSelection attribute:
<dvx:ASPxTreeList ... >
...
<SettingsCookies Enabled="true" StoreSelection="true" />
...
</dvx:ASPxTreeList>
If SettingsCookies doesn't work try saving and restoring the TreeList layout manually using ASPxTreeList.ClientLayout event. Define the event handler first:
<dvx:ASPxTreeList OnClientLayout="dvxTreeList_ClientLayout"... >
...
</dvx:ASPxTreeList>
and follow the example in the doc to handle this event. This way ASPxTreeView as well as the ASPxGridView provide the node/column format data in the e.LayoutData string which can be saved to DB and then restored back.
Store the TreeView selected node keys in Session and restore them using callbacks:
Example: ASPxTreeList - How to store the selection between requests
I personally would not rely on cookies and would try methods #2 and #3 first. #2 has been working nicely for me with ASPxGridView and #3 we use in a complex ASPxTreeView setup which also tracks the selection of hidden nodes.
I hope the examples in the linked docs should be easy enough for you to copy and modify. If not, comment what is not working for you.
HTH

Related

Referencing the TreeView from other TreeViews

I have a window form that has a control treeViewMain and in the code I have a list of treeViews that has variable number of treeViews. I want the treeViewMain to show anyone of the treeView from the list.
treeViewMain=treeViews[0];
but the form is not showing the tree. Also I have thoroughly checked the treeViews in the list, they are populating correctly.
Apparently simple assigning does not work. According to this post it seems that the parent of a TreeViewNode has to be unique and there by the "fruit" can only sit at one tree.
One workaround could be to set the parent property of the TreeView in your list to the treeViewMain:
treeViews[0].Parent = treeViewMain;
this will put the treeview from the list as a child inside treeViewMain. If you want to change that and load the next item from your list you need to make sure that the previously loaded item's parent property is set to null before assigning a new parent like in this example:
private int count = 0;
private void button_ChooseTreeView_Click(object sender, EventArgs e)
{
if (count > 0)
{
treeViews[count -1].Parent = null;
}
treeViews[count].Parent = treeViewMain;
count++;
}
The other possibility would be to clone each node and populate the treeViewMain each time you want to update the list items to the display

C# System.Windows.Automation get element text

I am trying to get text/labels from application controls with Automation in C#.
So far I am able to obtain AutomationElement tree of application (for example Notepad) with this function:
private void WalkControlElements(AutomationElement rootElement, TreeNode treeNode)
{
AutomationElement elementNode = TreeWalker.ContentViewWalker.GetFirstChild(rootElement);;
while (elementNode != null)
{
TreeNode childTreeNode = treeNode.Nodes.Add(elementNode.Current.ControlType.LocalizedControlType);
// here I want to get text from 'elementNode'
WalkControlElements(elementNode, childTreeNode);
elementNode = TreeWalker.ControlViewWalker.GetNextSibling(elementNode);
}
}
I tried to follow this article http://msdn.microsoft.com/en-us/library/ms788751(v=vs.110).aspx but it only can get text attributes as font name, font weight and so on.
Could anybody point me to the right procedure how to get element text with Automation?
That sample is showing you how to get text attributes, i.e. information about the display of the text in the UI, not the actual displayed text. Getting all the actual displayed text for a general application is more difficult that it might first appear.
It is made difficult by the fact that there are several ways get text and there is inconsistent support by applications and controls. There are two patterns that are of some use, ValuePattern and TextPattern. By convention the Name property contains text displayed to the user however adherence to this is inconsistent. Below is a helper method that I've used in UI automation for testing. It basically goes through those patterns checking the control for support and falls back to the Name.
public static class AutomationExtensions
{
public static string GetText(this AutomationElement element)
{
object patternObj;
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out patternObj))
{
var valuePattern = (ValuePattern)patternObj;
return valuePattern.Current.Value;
}
else if (element.TryGetCurrentPattern(TextPattern.Pattern, out patternObj))
{
var textPattern = (TextPattern)patternObj;
return textPattern.DocumentRange.GetText(-1).TrimEnd('\r'); // often there is an extra '\r' hanging off the end.
}
else
{
return element.Current.Name;
}
}
}
This takes care of getting the text out of simple controls like labels, textboxes (both vanilla textbox and richtextbox), and buttons. Controls like listboxes and comboboxes (esp. in WPF) can be tricker because their items can be virtualized so they may not exist in the automation tree until the user interacts with them. You may want to filter and call this method only on certain UI Automation control types like Edit, Text, and Document which you know contain text.
Mike Zboray answer works fine. In case you have access to pattern-Matching, here is the same (condensed) code :
public static class AutomationExtensions
{
public static string GetText(this AutomationElement element)
=> element.TryGetCurrentPattern(ValuePattern.Pattern, out object patternValue) ? ((ValuePattern)patternValue).Current.Value
: element.TryGetCurrentPattern(TextPattern.Pattern, out object patternText) ? ((TextPattern)patternText).DocumentRange.GetText(-1).TrimEnd('\r') // often there is an extra '\r' hanging off the end.
: element.Current.Name;
}

how to get xml data to listbox

ive got a problem with getting my data from a xml file to an listbox.
this is the data i want to get in my listbox:
<gjester>
<gjest>
<id>test</id>
<fornanv>test</fornanv>
<etternavn>test</etternavn>
<adresse>test</adresse>
<telefonnr>test</telefonnr>
</gjest>
</gjester>
and i created a listbox in my gui. But i don't know what to write in my code.
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
I don't know what to write here
}
There are approximately a bazillion ways to add items from an XML file to your listbox but a good place to start would be the MSDN documentation for the XMLTextReader class and the ListBox.Items.Add() method.
Also - you will probably want to do this somewhere other than the SelectedIndexChanged event on the listbox. For learning purposes, try it on a button click.
Good luck - and after looking into the above I'm sure someone will help you if you haven't figured it out.
This is .NET 4.0 (VS2010 C#) and is completely untested but may give you a start....
private void FillListBoxWithThingsIWantToSelect()
{
XDocument ListBoxOptions = XDocument.Load(Filename);
foreach (XElement element in ListBoxOptions.Root.Elements())
{
if (element.Name.LocalName.Contains("gjester"))
{
foreach (XElement subelement in element.Elements())
{
if (subelement.Name.LocalName.Contains("gjest"))
{
// What do you want to add? The Attribute? Element value
listbox1.Items.Add(element.Value.ToString());
}
}
}
}
}
Would help if you listed your platform and what you want in the listbox.
You want to call this from your constructor.
Can use dictionary object to bind the data from XML to Listbox.
var dic = (from order in ds.Tables[0].AsEnumerable()
select new
{
UserView = order.Field<String>("Value"),
DevView = order.Field<String>("id")
}).AsEnumerable().ToDictionary(k => k.DevView, v => v.UserView);
Click here for reference

Show only a part of an ItemsControl's source at first

I have an ItemsControl displaying a collection of files. Those files are sorted by most recent modification, and there's a lot of them.
So, I want to initially only show a small part (say, only 20 or so) of them, and display a button labelled "Show More" that would reveal everything when clicked.
I already have a solution, but it involves using a good old LINQ Take on my view model's source property. I was wondering if there was a cleaner way.
Thanks.
Why not have the object that you assign to the ItemsSource handle this logic - on first assignment, it would report a limited subset of the items. When Show More is clicked, the object is updated to show more (or all entries) and then notifies the framework that the property has changed (e.g. using the IPropertyNotifyChanged).
public class MyItemSource
{
private List<string> source = { ... };
public MyItemSource()
{
this.ShowThisMany = 20;
}
public int ShowThisMany
{
get;
set; // this should call\use the INotifyPropertyChanged interface
}
public IEnumerable<string> this[]
{
return this.source.Take(this.ShowThisMany);
}
}
...
MyItemsSource myItemsSource = new MyItemsSource();
ItemsControl.Source = myItemsSource;
...
void OnShowMoreClicked(...)
{
myItemsSource.ShowThisMany = 50;
}
In order to do this, you need to create some sort of 'view' on your data. There is nothing within the WPF framwork that will give you this functionality for free. In my opinion, a simple bit of Linq, Take(), is a clean and simple solution.

Getting the SelectedIndex of a child node in a TreeView

I am currently working on a wpf project in C#.
I have a treeview created that has parent nodes with childen nodes inside of it.
I was wondering if there was a way to get the index of the child node the user clicked on. (Simmilar to ".SelectedIndex" when using comboboxes)
I have tried Various ways such as:
int val =TreeView.SelectedItemProperty.GlobalIndex;
and
fileInput.IndexOf(treeView1.SelectedItem);
But they dont seem to work.
Any suggestions or comments are greatly appreciated.
Thanks
may you have to loop over tree nodes to get the index of SelectedItem. you can do that using OnItemSelected event.for ex.
Int32 selectedNodeIndex=-1;
private void TreeView1_OnItemSelected(Object sender,RoutedEventArgs e)
{
Int32 index=0;
foreach(var _item in TreeView1.Items)
{
if(_item==TreeView1.SelectedItem)
{
selectedNodeIndex = index;
break;
}
index++;
}
}
This post discusses exactly what you need I think. About handling the SelectedNodeChanged event and also a custom piece of code for an event that fires when the currently selected node is clicked...because then the SelectedNodeChanged doesn't fire (the selected node doesn't change actually). Good luck!

Categories

Resources