WPF treeview. Is there a way to add a child node to an already populated treeview without having to run in a for/foreach to check the header then converting that into an TreeViewIem ?
private void AddChildNode(string _rootNode, string _childeNode)
{
foreach (TreeViewItem node in tvSQLTasks.Items)
{
if (node.Header.Equals(_rootNode))
{
node.Items.Add(new TreeViewItem() { Header = _childeNode });
}
}
}
Create an ObservableCollection collection of objects, populate the collection with objects representing what treeview is supposed to display and bind that collection to ItemSource property of your TV.
Binding is the only proper way to go about populating your treeview with items in WPF and if you use the ObservableCollection you'll have the added benefit of items added to/removed from the collection "automagically" appearing in/disappearing from your TV without writing any additional code.
Depending on how complex your treeview needs to be you might have to use HierarchicalDataTemplate and ItemStyleSelector.
Related
I'm facing issue in binding single row to the treelist. In my application I have a two forms. first form contains treelist it will contain list of rows.
I need a selected row from the list. Using
public object selectedRow
{
return treelist.GetDataRecordByNode(treelist.FocusedNode)
}
using this code I get the selected row.
In second Form, I'm trying to bind that row.
public void row(selectedRow)
{
treelist2.DataSource=selectedRow; //I get the row value here.
}
But data not able to shown in second treelist. what step I need to do to bind a selectedrow to second treelist.
the DataSource should be an IEnumerable-type.
try something like this (pseudo-code ahead):
public void row(selectedRow)
{
List<yourType> list = new List<yourType>();
list.Add(selectedRow);
treelist2.DataSource=list;
}
Please go through TreeList's Data Binding section, Data Binding topic provides the complete information on binding the TreeList to data.
You can find reference to bind it with class objects here -
Binding Controls to Data Created at Runtime
In your row method, you should either create a List<ClassType> or BindingList<ClassType> before assigning the data source property. A list of ClassType objects can be created and bound to a data-aware control as follows:
BindingList<ClassType> list = new BindingList<ClassType>();
treelist2.DataSource = list;
References:
DevExpress TreeList not displaying child nodes and displaying as root nodes instead
binding data to the treelist control
Binding data in DevExpress Treelist from database
I have a combobox binded to an observable collection through
cmbBladesTab1.ItemsSource = easyRunData.olstBlades;
that works fine.
I want the combobox to be binded to all that values plus one.
E.g.
easyRunData.olstBlades; contains "PL1", "PL2", "PL3", "PL4"
while cmbBladesTab1 contains "ALL BLADES", "PL1", "PL2", "PL3", "PL4"
--ADD all work has to be done from code-behind
Thanks for your help.
You could add a property, that adds the particular item to the list.
ObservableCollection<string> myCollection;
ObservableCollection<string> MyCollectionViewProp
{
get
{
var tempCollection = new ObservableCollection<string>(myCollection);
tempCollection.Add("Extra element");
return tempCollection;
}
}
Depending on the size of the collection and the number of times it is accessed, this is probably the programmatically simplest solution. If you need to access it often, the worse this solution gets, as it creates a new collection every time.
In this case you should probably listen to the CollectionChanged event and keep a separate redundant list.
Easiest way would be to add an extra item in the observable collection with some prefixed text / key.
That way, because it's in the collection, it will be visible in the combobox and when the user selects this item you can evaluate it to see if it's the added item or not.
A good example is indeed given as an answer on this question add an item to combobox before bind data from data base
I am trying to bind my collection to a listbox. The collection contains some items which are to be hidden and are to be shown based on certain conditions.But when I do this the alternate styles are not applied properly.
For example:
Case 1 : where all items are visible, I get the output like this:
Item1(grey)
Item2(white)
Item3(grey)
Item4(white)
Item5(grey)
Item6(white)
Item7(grey)
Case2: where Item2 is hidden, I get the output as:
Item1(grey)
Item3(grey)
Item4(white)
Item5(grey)
Item6(white)
Item7(grey)
How do I resolve this without rebinding the collection?
Rather than hide the items (presumably in the ListBoxItem control template, or the ListBox ItemTemplate), you should use a CollectionViewSource to filter them out.
This is because the items are still technically there - you cannot see them but the listbox can.
See this link for details on filtering.
http://wpftutorial.net/DataViews.html
To filter a collection view you can define a callback method that
determines if the item should be part of the view or not. That method
should have the following signature: bool Filter(object item). Now set
the delegate of that method to the Filter property of the
CollectionView and you're done.
ICollectionView _customerView = CollectionViewSource.GetDefaultView(customers);
_customerView.Filter = CustomerFilter
private bool CustomerFilter(object item)
{
Customer customer = item as Customer;
return customer.Name.Contains( _filterString );
}
I am trying to retreive data from XML and if variable1 == variable2, it will add the element (listboxitem) to 2 parent elements (listbox - listbox1, listbox2). I am trying to use the following code:
if (variable1 == variable2)
{
ListBox1.Items.Add(ListBoxItem);
ListBox2.Items.Add(ListBoxItem);
}
else
{
ListBox1.Items.Add(ListBoxItem);
}
I was thinking to get around this i may be able to duplicate the ListBoxItem but im not quite sure how.
Any help very much appreciated :D
Thanks!
What you could do is build two ObservableCollections containing references to items from the xml data you've queried.
Instead of applying the logic above to ListBoxItem, apply it to each reference in the xml data and add the data to collection1 / collection2.
Then just bind collection1 / collection2 to listBox1.ItemsSource and listBox2.ItemsSource.
You have two listboxes referencing the same data then without the problems of duplicating ui controls within the tree.
Any control in wpf and silverlight can only appear only once in the object tree. So you cannot add one ListBoxItem to several ListBoxes. You can create a "copy" this way
ListBoxItem itemToClone = ...
ListBoxItem clonedItem = new ListBoxItem();
clonedItem.Content = itemToClone.Content;
So when itemToClone.Content is not itself a control but a string or a number you'll have two ListBoxItems showing the same content.
Hi all
I have a combobox which is databound to a list of elements. But in addition to that list of elements, i want to have another item. This item should display the text 'New...'
The idea is if they select one of the normal elements, it performs some action involving that element. If they select the 'New' element, it will take them to a screen where they can create a new item.
The problem is, When you databind something you dont get the option to add another item to it, and there is no question of adding a dummy item to the list of elements...
Is this an opportunity to create a new control based on the ComboBox which has a 'DefaultElement' property? (with all of the associated templating and command binding etc)
To do this I have previously created a dummy wrapper class for the normal type, allowing you to bind to a list containing mostly the correct values and also your "New..." one, e.g.
public class DisplayClass
{
public DisplayClass(ModelClass mc)
{
this.mc = mc;
}
public string Name
{
get { return this.mc != null ? this.mc.Name : "New..."; }
}
public bool IsDummy
{
return this.mc == null;
}
public ModelClass Model
{
return this.mc;
}
}
You can then host a collection of these in your data context (ViewModel), and handle the selection appropriately based on IsDummy. It's not as automatic as a control with this functionality built in, but is pretty simple and could probably easily be made generic and so reusable.
Set the ItemsSource property to a CompositeCollection with the new item and bound collection together, then detect that item's selection based on selected index or something similar.
Example Code:
<ComboBox>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem>Add New Item...</ComboBoxItem>
<CollectionContainer Collection="{Binding Source={StaticResource CollectionSource}}"/>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
MSDN for CompositeCollection: http://msdn.microsoft.com/en-us/library/system.windows.data.compositecollection(v=vs.110).aspx
Keep in mind that what you bind to is a UI oriented collection of items which can be different than the business or data entities.
If I were you, I'd insert a 'new' entity in the first position of the bound collection and detect it in my viewmodel to trigger the appropriate action when the user selects it.