views:

91

answers:

2

Hello, I am constructing my app infra structure, and finding it hard to achieve a very basic behavior - I want to raise events from different user controls in the system and being able to catch those events on some other user controls that listens to them. For example i have a user control that implements a TreeView. I have another user control that implmements a ListView. Now, i want my ListView to listen to the TreeView, and when the selection is changed on the TreeView, i want to repopulate my ListView accordingly. I also want this to happen even if the ListView is not located within the TreeView on the WPF logical tree.

PLEASE HELP!!

Thanks, Oran

+2  A: 

This is the point where the added complexity of MVVM (Model-View-ViewModel pattern) can start to pay off. What you need is a publish/subscribe infrastructure, and MVVM Light has that, along with good MVVM structure that doesn't get overly complex. Prism is another good WPF/Silverlight infrastructure foundation with publish and subscribe support.

Cylon Cat
Thank you. I am having rough time getting into WPF (From Java). I cant think of learning 3rd party stuff now...I hope looking into it in the future...Many Thanks,
OrPaz
Both of these are open source projects, including Prism, which was developed by Microsoft. So neither of these is huge, like a whole third-party product. MVVM Light is actually fairly small. The thing is, what you're attempting to do isn't trivial, and even experienced WPF developers will use one of these, or something similar, or develop their own. But what you're attempting to do will probably work better with commands, and almost certainly needs publish and subscribe, since one user control can't truly count on what other user controls may or may not be present at any particular time.
Cylon Cat
(continuing) Both Prism and MVVM Light use commands for their publish/subscribe support. If you want to roll your own, the place to put a publish/subscribe support would be in the application level (code-behind.for app.xaml is easiest). That will always be present, and any user control can publish and subscribe to a single service that way.
Cylon Cat
Thanks you! You really helped me acknolweding that it is not trivial, as i actually felt it while trying to implement it. It is very trivial to message components from components to regular windows programming...Anyhow, i will take a close look into those projects you mentioned above. Another thing : you mentioned publish/subscribe - are you talking generally about a pattern, or is there some kind of implementation already present in WPF ?Thank you
OrPaz
Both pattern and implementation. Both Prism and MVVM Light have publish/subscribe implementations, specifically for WPF and Silverlight. That's why I recommended them. As for messaging... WPF is just different from Winforms. You can use event handlers for messaging, if you can establish a reference to the object with the event handler - easier said than done, sometimes. WPF's databinding is based on observer and notification patterns, implemented partly in WPF and partly in either the .NET framework (ObservableCollection class) or application code.
Cylon Cat
MVVM Light has a getting started page at http://galasoft.ch/mvvm/getstarted/ that may also help.
Cylon Cat
+2  A: 

Use data binding.

If the content of the list view is stored inside the object shown in the tree view you can just bind into the tree SelectedItem property.

Otherwise bind the tree SelectedItem to a property in your view models (or your window!) and in the setter of this property change the list that is bound to the list view ItemSource property.

You can see the technique in this series on my blog the post I linked to is the last post with the code download link, you'll need to read from the beginning of the series if you want the full explanation.

EDIT: Here's how I did it in one project: (the GridView definition removed since it's not relevant here)

    <TreeView 
        Name="FolderTree" 
        Width="300" 
        ItemsSource="{Binding Root.SubFolders}"
        ItemTemplate="{StaticResource FolderTemplate}"/>
    <ListView 
        Name="FileView"
        ItemsSource="{Binding ElementName=FolderTree, Path=SelectedItem.Files}">
    </ListView>

The list bound into the tree view's ItemsSource is of objects that have 3 properties: Name (that is bound to a TextBlock in the FolderTemplate), SubFolders (that is likewise bound to the HierarchicalDataTemplate.ItemsSource property) and Files that is bound to the ListView using {Binding ElementName=FolderTree, Path=SelectedItem.Files}

Note that non of the lists are observable collections (because in this project they never change) but are loaded lazily (on-demand) by the properties getters (because in this project they are expensive to load).

Nir
Thank you. Actually i am using data binding from the listview on to other elements of the application. But i cant do the same for the treeview as it does not support the ObservableCollection pattern. To make it simple : I just want to be able to simply send messages (with data) from different parts of the applications to different parts, even if the sender is not nested within the getter. e.g : <Window> <TreeView "Send A Message To The World".../> <ListView "Get The Message That Relates To Me".../> </Window> STILL REQUESTING HELP :) WILL APPRICIATE SOME DEMO CODE... :) Thanks...
OrPaz
@OrPaz - I've added a sample, this is the way I did it and the cleanest way I can do it in WPF, you can't make a control broadcast a message to the world and even if you could you can't make another control magically understand it. If you wand to use commands or events all you have to do is write good old code-behind that will get the event from the TreeView and update the ListView.
Nir
Thanks Nir. This is great stuff. I think i got the picture better now. One last question(for now :) ) please : I was offered also to use some third party stuff to implement ModelView design patterns(MVVM light or Prism) and get stuff going easier. Althugh im familiar with mixing libs together(coming from java), i tend to use WPF core stuff, and build my own mechanism. But if these libs are most have, i will get into learning and using them. What do you think : Would you greatly recommend using those, or going 'plain' WPF is better?Many Thanks...
OrPaz
@OrPaz - I've never used MVVM light or Prism so I can't comment on them. the MVVM pattern makes a lot of sense for WPF but it has some weaknesses and each MVVM framework solves those differently - so you need to choose the one that suits you project and programming style - or - you can use plain WPF without an MVVM framework, WPF works fine without MVVM (the only thing most MVVM frameworks gives you is the ability to write unit tests). I recommend watching this before choosing a framework: http://live.visitmix.com/MIX10/Sessions/EX15 (just to see the potential, not to write your own)
Nir
(continuing) I said I can't comment on Prism and MVVM light but I must say, in my personal opinion, without saying anything about a specific library, that the publish/subscribe systems in MVVM libraries are global complicated solutions to local simple problems and replacing a one-line code-behind solution with a monster messaging system just to preserve "the architecture" and to support "testability" (in quotes because those tests must be just as over complicated as the app) is not productive. I would not choose a framework that needs global settings to support closing a form properly.
Nir
Thank you very much...
OrPaz