Data binding in WPF TreeListViews

TreeViews with multiple columns are one of those things that come up again and again, and I’ve been looking at this as part of some work we’re doing with Windows Presentation Foundation. The classic proof of concept was posted by the Avalon team back when WPF was still called Avalon, but it doesn’t play nicely with WPF data binding. In the demo, the authors explicitly construct a bunch of TreeListViewItems in their XAML, which works fine; but if you try to databind the sample via the ItemsSource property, it all grinds to a halt. The top-level items come up fine, but they’re not expandable.

To see why, let’s back up a little. A WPF TreeView contains a collection of TreeViewItems. TreeViewItems are visual objects. So what actually happens when we databind a graph of “normal” objects to a TreeView’s ItemsSource property? Behind the scenes, the TreeView creates a TreeViewItem for each bound object, and uses the TreeView’s ItemTemplate to create content for that TreeViewItem. The ItemTemplate is of type HierarchicalDataTemplate, which has an ItemsSource property of its own. The TreeViewItem in turn creates child TreeViewItems from the ItemsSource.

But in the TreeListView demo, presentation is handled by a GridViewRowPresenter via the TreeListViewItem control template: there’s no need for an item-level data template. And without an item-level data template, there’s no ItemsSource property to tell the TreeListViewItem what to create on the “next level down.” How do we address this?

It turns out that, although it’s not needed and not used in presentation, we can still specify an ItemTemplate for the TreeView. This is a bit confusing, because the content of this template is completely ignored: the presentation is still handled entirely by the GridViewRowPresenter. In fact, the template can be completely empty. The only thing that matters is that the template exists, that it’s a HierarchicalDataTemplate and that its ItemsSource property is set. All it’s doing is giving the WPF data binding infrastructure somewhere to find the directions to the next level down.

Once you do this, you can databind to the sample TreeListView control just as to any TreeView.

UPDATE: Mindscape WPF Elements includes a TreeListView control (mysteriously renamed the MulticolumnTreeView) which provides full support for databinding as well as a simpler, more encapulated API. Check it out or download the trial.

Tagged as General

38 Responses to “Data binding in WPF TreeListViews”

  • HI,

    thanks for your explanation. I was trying the TreeListView sample and it seems I cant make it work as it should. The problem with your explanation is that I am new to WPF and I could not really understand it all. Could you give an example?

    Thanks a lot!

  • I’ll do my best, but you will need to be familiar with the normal WPF way of populating ItemsControls using the ItemsSource and ItemTemplate properties. These properties enable you, instead of constructing ListBoxItems, ComboBoxItems, etc. explicitly for the list entries, to just point the ItemsControl at a collection and say “I want a list entry for each item in the collection, and this is how I want it displayed.” If you’re not familiar with this approach, check out the documentation, Bea Costa’s blog and/or my post on WPF data visualisation at http://www.mindscape.co.nz/blog/?p=69.

    Now the problem with the ATC TreeListView sample is that it doesn’t support this idiom. The top-level items in the tree get displayed, but they’re not shown as expandable. This happens because a TreeView in ItemsSource mode needs somehow to figure out, given an item, what are its children. The way it does this is to consult the ItemTemplate. In the case of a TreeView, this is a HierarchicalDataTemplate, and its ItemsSource property tells the TreeView what should appear at the next level of the hierarchy.

    So in order to get the ATC sample working in databound mode, we need to supply a HierarchicalDataTemplate as the ItemsTemplate, *even though the actual appearance of the items is handled by the GridViewRowPresenter* (and that any visual components of the template will be ignored).

    Okay, what do we need to do in practice?

    First, you need to create some hierarchical data as an object model. For example, you could create a TypeInfo class with Name, IsAbstract, Namespace and DerivedTypes properties. (Keeping these same properties saves us having to change the column declarations in the ATC sample.) Then create a a collection of these objects to be your data source.

    Now open Window1.xaml, and in the section, add:

    Notice the ItemsSource attribute here. This is what specifies that the DerivedTypes collection is what should be used to form the next level down.

    Still in Window1.xaml, change the TreeListView start element as follows:

    This is the usual syntax for hooking up an ItemsControl to an item template.

    Leave the TreeListView Columns intact, but get rid of all the TreeListViewItems.

    Finally, in the Window1.xaml.cs code-behind, in the constructor, add the following line:

    theTreeListView.ItemsSource = TypeInfo.Samples;

    where TypeInfo.Samples is the sample collection data source you created earlier.

    If this doesn’t work, or doesn’t make sense, I’d suggest you first test your sample collection data source with a normal TreeView and a “real” HierarchicalDataTemplate. Once you have that working, it should actually port to the TreeListView sample without any changes required.

  • Hi Ivan,

    thanks! I am familiar with ItemsSource but I only used it with comboBoxes. Your example works fine :)

    It is really bad for a start to have to do such a complex control. I need a TreeListView but with some add-ons to the sample from ATC like:
    – zebra background for the lines
    – editable cells in the columns part of the tree
    – a scrollbar
    – lines dividing the columns
    and I also need to figure out why the line separating the root element from the children doesnt appear!

    Do you know if all that I need is possible?
    (I also asked the same question in to ATC).

    Thanks again for you help!

  • Yes, all this is possible by adjusting the template for TreeListViewItem and the DataTemplates for the cells (e.g. using TextBoxes instead of TextBlocks). Use a ScrollViewer to get the scrollbar. You will probably need to do some fairly fine manipulation of Border elements to get the column-delimited lines and zebra backgrounds. For the zebra background, you will probably also need either to further subclass TreeViewListItem or to wrap your items, so that you can get the row number to where it’s needed.

    Alternatively, you might want to look at our WPF Property Grid (www.wpfpropertygrid.com) which does a certain amount of this already and might save you the effort!

  • We have done everything suggested above to bind treelistview with HierarchicalDataTemplate. Although other columns also gets indented as treeview colum does. We don’t want other columns to move with tree view childs.
    It looks like this:-

    From DATE
    – Root 10/10/2008
    Child1 10/11/2008
    Child2 10/12/2008
    + Root1 11/10/2008

    Any help here would be appreciated.

    Thanks

    Pravin.

  • Hi Pravin,

    This is probably to do with where the LevelToIndentConverter is being applied. Make sure that the indent is applied as a margin to the Expander ToggleButton (within the cell template for the leftmost column) and not to the TreeListViewItem or to anything in the TreeListViewItem control template.

  • Hi Ivan,

    Thanks for your reply, I found out that the problem was not with TreeListView/LevelToIndentConverter but with some other style I was using for showing hierarchy lines.
    Although I couldn’t fix it, seems like I have to go with a plane TreeListView without showing hierarchylines.

    Thanks

    Pravin

  • Hi Ivan,

    thanks for confirming the possibility of implementing what I need!
    I have the scrollViewer (it was very easy) but I was momentanly working on other thing.
    Now I am back with the TreeListView and I need to ask you some more questions. On the ATC example they define a GridViewColumnCollection with a set of static columns. In my project the columns are decided at runtime because they depend on some data that comes from the db.
    How can I define the columns programatically and maintaining the link to the treelistview? I tried setting the Columns property but it get overriden by the static definition. I also tried changing the static resourse to dynamic but with no sucess (I guess it makes not much sense if the xaml initialization is still there).

    Let me know if I didnt explain my problem correctly.

    Thanks in advance!
    Filipa

  • Hi Filipa,

    Setting the Columns collection at runtime works for me: as one would expect, the new Columns collection overrides the one defined in the XAML. Alternatively, you can use the Add, Remove and Clear methods to modify the collection at runtime. This also works for me in a quick test.

    I’ve only tried doing this from code. It might be possible to do it through databinding if that’s what you need — not sure offhand.

  • humm, but do you still have the GridViewColumnCollection defined on xaml?
    I still have doubts about what should go to xaml and how the correspondence between xaml and code is made.

    Can I define the 1st column in xaml and then add other columns in code?

    I tried adding columns to the Columns property of the TreeListView, when I debug I see them there but in the interface I still see the ones defined in xaml. I don’t know what I am doing wrong.

    Thanks!

  • Hi Ivan,

    forget my last questions. I already read and understood how it works :) and it works!

    Anyway I have another question:
    I am working now in making the cells editable by poping-up a window because the values displayed in these cells are the result of a formula. In the pop-up the user will be able to edit this formula. So, what I really want is to maintain the cells as TextBlocks and somehow assign a Click event to each individual cell. Is this possible?

    Thanks again!

  • TextBlock doesn’t have a Click event, though you could implement it yourself with suitable handling of the mouse events, or (perhaps better) by using a Button instead and styling it to *look* like a TextBlock. That aside, it is certainly possible to fire events from your cells. If your cell DataTemplate is part of your application (i.e. in a Window or Page) then you can just wire up the event to a handler in the corresponding class in the normal way. If your cell DataTemplate is part of a ResourceDictionary then it is easier to use a Command instead (but again a TextBlock does not support commands). I have some discussion on this at http://www.mindscape.co.nz/blog/index.php/2007/12/12/commands-and-controls-in-wpf/.

    What you will *not* be able to do is assign different event handlers (or different commands) to different cells in the same column (unless you use multiple DataTemplates and set CellTemplateSelector instead of CellTemplate). If you need to have different cells use the same DataTemplate but behave in different ways then the best way is probably to use a Command and a CommandParameter, because CommandParameter can be databound as part of your DataTemplate, and your command handler code can inspect the parameter and choose what to do accordingly.

  • Hi Ivan,

    thanks again for your help! My solution was, like you suggested, using a button but I thought maybe there was some better way. I hope I am getting the hang of it!

    I hope you don’t be bored about me always asking more and more questions. Guess what? I have another!

    I have the TreeListView ItemsSource binded to my hierarchical data that is an ObservableCollection. In my interface, I choose a tree, then press a button the tree loads (binding the corresponding data to the user’s tree choice). Everytime the user chooses another tree and presses the button again, the treelistview refreshes with the new tree but I want to have a moment in between where the tree is blank/cleared.

    I have read about ItemsControl and how to clear them here (http://www.drwpf.com/blog/Home/tabid/36/EntryID/18/Default.aspx) and tried to set it to null but with no success. I also tried to set it to an empty ObservableCollection, also with no success.

    Can you give me a hand again?

    Thanks a lot!

  • Setting ItemsSource to an empty collection should blank the control. However the blanking will not happen immediately: it will happen when your code (your event handler) stops running and the WPF runtime takes over again. (This is a slight simplification: check out the DispatcherPriority enumeration in MSDN for more detail.) So if you set ItemsSource to an empty collection and then immediately to your new data source, the user will not see the blanking. Instead you will need to set ItemsSource to an empty collection and then set a timer (see DispatcherTimer) to load the new collection.

    For a more “WPF-like” way of doing this you might want to consider using an animation or trigger to replace the content of the control with a message (e.g. “Loading…”) when the ItemsSource changes. I.e. instead of delaying the loading of the new ItemsSource, you would be delaying the *appearance* of the new data on screen. This keeps the presentation logic (blanking or whatever) separate from the actual behaviour (changing trees). I am not sure how practical this would be though.

  • Hi Ivan,

    thanks for you help.
    I finally finished my TreeListView with almost all the features I wanted.
    I am still missing the zebra rows and the click event for the buttons but all the rest is fine.

    Thanks again.

    Best,
    Filipa

  • Hi Ivan,

    I am working on the events on the cells from my TreeListView.
    As suggested by you the cells are styled as a Button and I have access to the Click event.

    My problem is how to know which cell was clicked because I can only see the information about the Button. I am probably missing something obvious here… can you give me a hand again?

    Thanks a lot!

    Best regards,
    Filipa

  • Hi Filipa,

    I haven’t tested this, but my instinct would be to use Button.Command instead of Button.Click. With this, you can databind the Button.CommandParameter property to whatever context/source information you need (e.g. the object that is being presented in the row or cell at hand), and in your Command_Executed event handler, you can extract this parameter.

    If you want to stick with Click, you can probably do something similar by databinding Button.Tag, and in the Click event, cast the sender to Button and get the data out of the tag. But Command/CommandParameter is cleaner.

  • Hi Ivan,

    thanks for your answer.

    I understand what you suggest but my problem is a little before that suggestion. I probably didn’t explain correctly.

    The problem is I don’t know how to access the row that contains the clicked button because when I click the button the row remains unselected because the button covers it (therefore I am unable to use the SelectedItem property).

    In the event attached to the button, as far as I can see, one can only see the Button itself and not the object that represents the row in the TreeListView to which the button belongs.

    This is probably obvious but I am not reaching the solution.

    Thanks!

  • Again, I haven’t tested this, but if you set CommandParameter to something like “{Binding RelativeSource={RelativeSource AncestorType={x:Type ns:TreeListViewItem}}}” that should work. (Some trial and error may be required.) The idea being to get the binding system to search up the visual tree for the containing TLVI, and then bind directly to that object (which will be the “row” object).

  • Hi Ivan,

    first of all thank you for your explanations about the TreeListView’s databinding principle.
    I have a problem with presenting XML-data with the TreeListView. My XML-Data consists of different types of nodes with different attributes and can be recursiv (node-type ‘X’ can have childs of node type ‘X’). What I need is a XML-node/attribute sensitive rendering. This works fine with a basic WPF-TreeView using a set of HierarchicalDataTemplate’s which defines the XML content-layout and defines the rendering of each specific XML-node. But with the TreeListView this way seems to be closed because the rendering of a TreeListViewItem is anchored more or less static in the GridViewColumnCollection bunch. I have searched through a lot of examples and WPF-documention but cannot find something appropriate.

    Do you have a hint a solving this proleme, maybe with the CellTemplateSelector attribute from GridViewColumn?

    Thank You!

    Best regards,
    Thomas

  • […] A commenter on a previous post asks about using XML data in a TreeListView and specifically about how to vary the display in a way which is sensitive to the XML nodes and attributes. The techniques I posted about for displaying heterogeneous object hierarchies apply pretty much identically to XML, so here’s a brief primer on using XML in the WPF Elements MulticolumnTreeView. […]

  • Hi Thomas,

    I’ve just shipped an article about how to customise the display of object hierarchies in our MulticolumnTreeView (aka TreeListView), and have posted an update for XML at http://www.mindscape.co.nz/blog/index.php/2008/04/30/wpf-elements-multicolumntreeview-and-xml-data/. (It is probably a good idea to follow the link back to the earlier article to get some context before getting into the XML stuff.) Short answer: yes, you’re right, CellTemplateSelector is the way to go for basic customisation, with an upgrade to StyleSelector and custom control templates if you want to break out of the column layout altogether.

    The articles are written in terms of our WPF Elements tree-list view control, but if you don’t want to use that control, the techniques should be adaptable to the modified ATC sample discussed in the post above.

  • Hi Ivan,

    thanks a lot for your help, it solves my problems.

    Best regards
    Thomas

  • Hi Ivan,

    first of all thank you for your explanations about the TreeListView’s databinding principle. I have a new problem with DataBinding to XML in my customized TreeListView. My first prototype based on the XmlDataProvider and all things work fine. Then using xsd.exe on my XSD-definition of the XML-data I generate a C#-class collection representing the actual XML-document. I tried to bind this hierarchical bunch to my TreeListView via an ObjectDataProvider but the TreeListView stays empty. I figured out that all Types that you will bind to my TreeListView via HierarchicalDataTemplate has to implement the IEnumerable. Unfortunately the xsd.exe generated classes don’t do this, so I tried out doing this on my root-class, but the nevertheless the TreeListView stays empty. So my question would be: Is there a simple/short solution to bind a xsd.exe generated class-hierarchie to a TreeView-based control?

    Thank You
    Best Regards
    Thomas

  • Hi Thomas,

    Rather than using an ObjectDataProvider, use code-behind to set the ItemsSource to a single-element array containing the object you want to display in the tree:

    tree.ItemsSource = new MyClass[] { myObject };

    Once you have done this, child collections will display automatically (provided you set them up via the HierarchicalDataTemplate.ItemsSource).

    Another possibility might be to explicitly create a TreeViewItem with the root object as its content:

    Note that, whichever approach you take, non-collection properties will not display as tree elements: the HierarchicalDataTemplate.ItemsSource is always a collection. You would typically display non-collection properties via the columns of a TreeListView (or the content of the HierachicalDataTemplate in a traditional TreeView). If you need to display non-collection properties as tree elements then you will need to create a view model which exposes the set of properties as a collection, and bind the TreeListView to that, or use a control such as our WPF Property Grid (http://www.mindscape.co.nz/Products/WpfPropertyGrid/default.aspx) which does this for you.

  • Hi Ivan,

    thanks a lot for your very fast response.
    Unfortunately it helps not much. It seems that there is a general break in the microsoft tool-set concerning XML-Schema and presenting XML-content with the basically very powerful WPF-binding mechanism.
    Consider a common situation working with XML:
    To constrain a bunch a XML-definitions you developing a schema which describes all the stuff. Then you take the Mirosoft XSD-tool and generate a native (C# in my case) class hierarchy, because it gives you the freedom working with an appropriate OO-representation of your XML-data. Loading, Saving and Manipulating of the XML-Data in this way works very fine, it is always only a small number of code lines, thanks to the wonderful .NET XML support at this point. Then you start to fulfill the requirement of presenting the data to the user via GUI. As long as you use the XMLDataProvider it is quit easy to get good results, but by using the XMLDataProvider there is no need to have the XSD-generate classes, it works directly on your XML-stream. But using the XMLDataProvider you are always move on the ‘XmlElement’-layer if you want manipulate the XML-data via GUI. So you try to switch from XMLDataProvider to another approach which brings the generated class-bunch into the game, but this seems a hard work to to, especially if the class-bunch consists of more than 50 classes. So the overall questions stays: Why is the way from XML-Schema over XSD.exe to powerful hierarchical databinding to GUI-controls so stony?

    Best Regards
    Thomas

  • Hi Thomas,

    I don’t entirely agree that there’s a “break” concerning XML deserialisation and the WPF binding mechanism. One of our test applications for our own MulticolumnTreeView control, for example, does exactly what you describe — it reads an XML file into an object graph using the XmlSerializer, and displays that object graph in a tree-list format. We had no problems getting this working.

    That said, you are right that xsd.exe is falling behind compared to WPF’s native XML support. For example, although xsd.exe has the /edb switch to tell it to implement INotifyPropertyChanged, there isn’t a corresponding option to generate ObservableCollections instead of arrays. In the example above, I didn’t bother writing an XML Schema and running xsd.exe over it — I just wrote the class definitions by hand (because I find it easier to write C# than XSD *grin*). But I can imagine that with 50 classes that you already have XSDs for, you won’t be wanting to do that!

    Anyway, I’m drifting off topic here. I’m not sure why you’re seeing the problem you describe with your deserialised objects — I see no reason why it wouldn’t work. If you want, drop me a project that reproduced the problem — mail it to ivan @ the obvious company address — and I’ll take a look at it and see if I can figure out what’s going wrong.

    Cheers,
    Ivan

  • Hi Ivan,

    I have a little problem with scrolling in my TreeListView. Basically I need content-scrolling in both direction. The probleme is the content-header which is defined with ‘GridViewHeaderRowPresenter …’. For vertical scrolling this header has to be sticked on it’s place to let the user see it. In contrast for horizontal scrolling this header has to be scrolled with the content to let the columns-header be sync with the columns.
    So it seems you have 2 options:
    1. One ScrollViewer around the GridViewHeaderRowPresenter for both directions, but then the header will disappear while scrolling vertical or
    2. One ScrollViewer around the GridViewHeaderRowPresenter.ItemsPresenter for scrolling only vertical and one ScrollViewer around the GridViewHeaderRowPresenter for horizontal scrolling only, but then the vertical scrollbar disappear while scrolling horizontal.

    Maybe you have a better solutions?
    Thank you

    Best Regards
    Thomas

  • Hi Thomas,

    For the WPF Elements MulticolumnTreeView (http://www.mindscape.co.nz/products/WpfElements/controls/TreeListView.aspx), we ended up doing the following:

    * The template for the MCTV control was a ScrollViewer containing the ItemsPresenter.

    * The ScrollViewer was given a custom template which was built up explicitly using a Grid. The top left cell of the grid contained a DockPanel which had a ScrollViewer (with all scroll bar visibilities set to hidden) containing the GridViewHeaderRowPresenter docked to the top, and the ScrollContentPresenter (where the rows will end up appearing) as the fill. The right and bottom cells of the grid had the scroll bars. These were named as per the ScrollViewer part naming convention to tie everything together. I.e.

    Grid
    +- DockPanel
    | +- ScrollViewer
    | | +- GridViewHeaderRowPresenter
    | +- ScrollContentPresenter PART_ScrollContentPresenter
    +- ScrollBar PART_HorizontalScrollBar
    +- ScrollBar PART_VerticalScrollBar

    I think the reason this works is that the wiring of the ScrollViewer means that only the contents of the ScrollContentPresenter (i.e. the rows of the list view) actually get scrolled by the ScrollViewer. Placing the GridViewHeaderRowPresenter outside the ScrollContentPresenter prevents it from being scrolled out of view. But the wiring of the GridViewXxxPresenters keeps the header horizontally in sync with the rows (the GridViewHeaderRowPresenter detects the main ScrollViewer and hooks its scroll events). It has been a long time since I looked at it though!

    If memory serves this is pretty much how the ListView/GridView does the same thing of always showing the header but having it sync with the horizontal scroll. You may therefore be able to get the effect you want just by applying GridView.GridViewScrollViewerStyleKey to your ScrollViewer (I can’t remember whether we tried this and it didn’t work, or whether we just rolled up our sleeves and implemented the custom style without bothering to try it!).

  • Hi Ivan,

    thank you very much for this explanations! I will check the next days whether this solves my problem.
    Currently I have another question concerning rendering-events of my TreeListView:

    As I told you some weeks ago my TreeListView maps non-static XML-data. I do this by having different DataTemplates in my XAML for different XML-nodes and a CellTemplateSelector for every column in my GridViewColumnCollection. Some of the rendering-work is defined in this Templates, but some I do programmatically in my C#-code. To to so I walk recursivly through all my TreeListViewItems by using ItemContainerGenerator-functionality and looking for the right ContentPresenter for the column to find the DataTemplate-generated GUI-elements to setup additional thinks like Binding with Converter etc.. This works fine for my initial XML-Document, which is currently wired directly in my XAML: I simply use the ContentRendered-event from my Main-Window to start the post-work. But, of course, I will the have the possibility to load another XML-doc from file: I create a new XmlDocument and load the file with the XmlDocument.Load() function. Than I acquire the XmlDataProvider from my XAML and set the XmlDataProvider.Document to my newly created XmlDocument. Than I call XmlDataProvider.Refresh() to trigger the update of the underlying internal Xml-tree and thereby the update of the whole TreeListView.
    Now comes the problem: After the XmlDataProvider.Refresh() I try to start the post-work, but it seems to be to early because all ItemsControl which I get from ItemContainerGenerator.ContainerFromIndex() are zero. The number of items per tree-level are right (not zero). This behavior will not change if I set the XmlDataProvider.IsAsynchronous property to false at start and try to use a later event to trigger the post-work like XmlDataProvider.DataChanged or TreeView.DataContextChanged. To check whether there is a general problem I use the TreeView.GotFocus-event and this works: That means if you open a new XML-doc in the way I discribed and trigger the post-work by using the focus-event the TreeListView is completely new rendered and all TreeListViewItems are there and accessable. But of course, this is no solution.
    So my question would be: Is there an event which is fired after the TreeListView is rendered ready so I can find all Template-generated GUI-elements?

    It would be very nice if you had a hint for me solving this problem.

    Thanks in advance and a good pre-christmas-time for you

    Best regards
    Thomas

  • Hi Ivan,

    forget my previous question, the solution I found is a simple TreeListView.InvalidateVisual() (inherited from TreeView) after XmlDataProvider.Refresh(). That triggers a new rendering and than the event-function TreeListView.OnRender() can be used for start the post-work.

    Best Regards
    Thomas

  • Hi Ivan,
    Thanks for your explanations, but I still have some issues with the treelistview I’m creating and hopefully you can give me a hand with it.

    Basically I’m using as reference the Avalon sample and Josh Smith’s OnDemandLoad example from his article http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx?fid=1342639&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=1#xx0xx .

    I have 3 ViewModels,RegionVM,StateVM and CityVM which is the one that should show its data in a few columns.

    In the resources, I’ve got the style for MultiColumnTreeView, setting its header with GridViewHeaderRowPresenter, another style for MultiColumnTreeViewItem …

    Within the MultiColumnTreeView, I have the HierarchicalDataTemplate for RegionVM and another HierarchicalDataTemplate for StateViewModel, but I have no DataTemplate for the CityVM as this should be bound in the MultiColumnTreeView.Columns, Is that correct ? Well I’m not sure how to show the CityVM’s data, I’ve bound them in the columns of the MultiColumnTreeView like this

    but it’s not working fine, as when I expand the States (the parent of Cities), I got the number of rows showing a string with the path of CityViewModel.

    Can you give me some assistance in how to show the data of CityViewModel in the proper columns?

  • Hi Txomin,

    You’re right that you shouldn’t need a template for the bottom-level items (the cities). And it’s expected behaviour that you’d get a number of rows under each State, one for each City. So I’m not quite sure what the problem is. Is it that what’s displayed against each City is incorrect? If so, it sounds like the problem may be with your column bindings, but the code showing how you’re doing the binding seems to be missing. It should look something like DisplayMemberBinding=”{Binding Name}” or CellTemplate=”{StaticResource NameTemplate}”.

  • Hi Ivan, thanks for your reply, I was able to solve the multicolumn issue, I was just doing a stupid xaml mistake, I suppose it’s part of the learning curve…
    I have another question though, how can I disable the Drag and Drop of the columns? I tried it overriding the OnDragLeave event and doing nothing in it, but it doesn’t seem to work…

  • Set AllowColumnReorder to false. (By the way, our WPF Elements collection includes a MulticolumnTreeView that already handles this for you. See http://www.mindscape.co.nz/products/WpfElements/controls/TreeListView.aspx for info.)

  • Hi Txomin,

    What is your stupid mistake ?

    Because I have done the same.

    Thanks.

  • Hi Ivan,

    Thanks for the amazing rundown. In your first comment response to filipa, the code segments that you may have added are all missing. Can you help put them back as I try to understand this?

    Thank you so much :)

  • Hi Salman,

    It was a long time ago but I don’t think I added any code segments — I just did some tests using the elements and methods I referred to, I didn’t make an actual sample of them. But it was a longish conversation and a long time ago so I may be misunderstanding what you’re referring to!

  • Leave a Reply

Archives

Join our mailer

You should join our newsletter! Sent monthly:

Back to Top