WPF / MVVM: Show specific image from list of images? - wpf

I have two lists of different object types in my ViewModel. For example I'd say the first one is a list of all available images, the second one is a list of all articles. Each article belongs to an article category for which I'd like to show a thumbnail in the GUI when an article is selected and shown. For the sake of a simple example I assume that the Id of the category equals the Id of the corresponding image.
For a ComboBox this would be an easy task: I would assing the list of all images as ItemSource and then the article's category key to the SelectedValue. The SelectedValuePath would have to point to the Id of the image.
However a ComboBox does not make sense here as I only want to display the correct category image - I do not want any editing, a dropdown, etc... How would I solve this with a regular Image-UserControl (or maybe a similar UserContro)?
BTW: Right now I have to use an additional Property on my Article class which directly holds the correct image, but I think there should be a better way to solve this issue.
Any ideas?
Regards
ralf

There's no problem with creating a get-only property on your ViewModel that provides the image that the view should bind to. The whole point of ViewModels is to shape model data into a structure suitable for binding views to.

Related

Dynamic Databinding in WPF

I am filling up a Stackpanel with Textboxes. Each textbox, Should display the Value Property of a Class i have written.
The number of Textboxes is always different so i can't create a databinding in the xaml file.
Are there tutorials, that show how can i archive my goal?
Edit: Thanks for the replies so far. After reading the articles i still not clear how to implement my Problem.
Here is what I'm trying to achieve:
I have an SQL Server DB and there a Table with an ID and a Value.
I now load all Values and IDs i want to display into my application. (number of loaded rows is always differnt).
I need to display a textbox for each row and display the value there and after the value is changed i write the value back to the database.
I don't know how I should query the data and than bind it to the textboxes.
I don't need an implementations, I am happy with every piece of advice I can get.
yes there are a number of tutorials out there. It sound like you are interested in datatemplating.
I would suggest looking Here on MSDN. A few tutorials on databinding in general may be useful DataBinding on MSDN
If your class, classValue, has a public property Value then just create a List and bind that to a ListBox with the item DisplayValuePath = Value. Repeater controls are used to bind to collections.

MVVM - What's the correct track regarding Nested Lists and View Models?

Here's the thing:
I have a GetHistoryLog View, its view-model, and its model.
I have a listbox which points to a ObservableCollection<ChangesetEntity>
I have another view specialized on getting versioned items, so it's a VersionedItemView, its view-model, and its model.
Now I want GetHistoryLog View to access specific versioned items within its changesets. Each changeset can have multiple versioned items. What is the best way to "connect" the two view-models?
Here's what I want to do, a Tree-view containing all the changesets and child files, and a single list view containing all the changesets, with an option to click the changeset and view the modified files.
Basically, access a list of items inside a list of items, and at the same time have the option to access a specific index inside this list.
Do I need to create another view-model? What is the best solution without creating havoc in the code?
I hope I was clear enough
Thanks in adv.!
EDIT: Also, is there a way to set the DataContext of a control to some specific item in a list, dynamically?
EDIT: Trying to explain more clearly:
HistoryLogEntryModel -> GetHistoryLogVM -> GetHistoryLogUserControl
VersionedItemLogModel -> GetVersionedItemsLogVM -> GetVersionedItemsLogUserControl
What I want is:
HistoryLogEntryModel + VersionedItemLogModel -> ? -> GetCompleteHistoryLogWithVersionedItemsUserControl
(shorter name, but just for understanding)
Based on your description, I don't think you need anything more. You already have a very hierarchical object graph of your domain which will support the parent child relationships you're describing already.
I think you just need to polish up on your approach to binding and object presentation. Here is a good post from MSDN magazine that can help you with that and it also has advice for dealing with with Hierarchical Data Templates for use with a WPF TreeView.
If you want to do a binding that dynamically changes the DataContext of a control based on the SelectedItem of another control (ListBox for example), you can use the following binding syntax:
DataContext="{Binding ElementName=sourceElementNameHere, Path=SelectedItem,
Mode=OneWay}"
Here is another link to a good MSDN article on binding in WPF.

How much coupling is appropriate between ViewModels in MVVM

I'm developing a fairly simple WPF application to display an object hierarchy plus detail of the selected object, with a UserControl wrapping a TreeView in the left pane (the tree control), and another UserControl wrapping a ListView/GridView on the right (the details control).
The tree control uses MVVM following this Josh Smith article reasonably closely, and has a number of ViewModel types all derived from the same base type, TreeViewModel. The main window is set up using a MainWindowViewModel as in this Josh Smith article and exposes the TreeViewModel used to populate the first generation of the tree control.
However, when I want to populate the details pane on the right, I have the problem that the SelectedItem of the tree control is derived from TreeViewModel when I need a completely different type of ViewModel for the details pane which will expand the object into a table of properties/values using reflection.
So, questions:
Is it appropriate for the MainWindowViewModel to expose the TreeViewModel for the tree control? I believe that the answer here is yes, but am open to suggestions to the contrary.
How should the selected item in the tree control be adapted to the right ViewModel type for the details pane? One option seems to be that the MainWindowViewModel tracks the selected item in the tree and does the adaption, exposing it as another property, but I'm not sure if there is a better solution.
I'm new to WPF and the MVVM pattern, so please excuse the fairly basic nature of the question. I've done a fair bit of reading around the background of the pattern, looked at some sample apps etc. but I can't quite find anything specific enough to make me confident of the answer. I also realise that MVVM may be overkill for an app this simple, but I'm using it partly as a learning exercise.
1.Is it appropriate for the MainWindowViewModel to expose the
TreeViewModel for the tree control?
I belive yes. The model should hide the look from teh logic FOR THE LOOK, but it can not hide thigns like logical structure.
2.How should the selected item in the tree control be adapted to the right
ViewModel type for the details pane?
One option seems to be that the
MainWindowViewModel tracks the
selected item in the tree and does the
adaption, exposing it as another
property, but I'm not sure if there is
a better solution.
IMHO not.
Working on the similar problem I came to the conclusion that
object Tag { get; set; }
property is inevitable :( except maybe for some rare situations (only 1 type of objects in the entire treeview).
However, when I want to populate the details pane on the right, I have the problem that the SelectedItem of the tree control is derived from TreeViewModel when I need a completely different type of ViewModel for the details pane which will expand the object into a table of properties/values using reflection.
If you're really, really concerned about this, you can build a higher-order view model class that exposes two different properties - one of type TreeViewModel and one of type DetailsViewModel. Then the main window's view model will expose the same object to both the tree control and the details control, but the logical structure of the two view types will be decoupled from one another.
Logically, the selected item in the tree control and the item that's appearing in the details control are the same thing. While the details control doesn't present information about the thing's parent/child relationships, and the tree control doesn't present information about the thing's name/value pairs, it's still the same thing. There's probably not really any need to be too concerned over the fact that a single object representing a thing exposes a property that only one view of that thing uses.

How to use two templates for ListViewItem using WPF

I would like to have a ListView that would have have items similar to Microsoft Outlook inbox with items arranged by Conversations (see the attached photo). An item can either be a simple textblock containing the topic of the conversation (on the photo this are the blue lines) or it can contain email information specified by the ListView's header. It would be best if the items with conversation topics would be push buttons so that emails inside that conversation could be shown or hidden by pressing this button.
Any ideas how can I achieve this? Do I specify two ListViewItem templates? If yes, how do I tell in the code which template to use for each item?
Any help will be GREATLY appreciated!!
Regards,
Gregor
alt text http://img401.yfrog.com/img401/1719/inboxy.png
You should check out DataTemplateSelector. just google it.
The idea is this.
You will define 2-3 templates in XAML
create a class derived from DataTemplateSelector and based on a field/ typeof object
you will return the appropriate template
The concept used in your screenshot is called Grouping. You can easily use grouping if you have a ListCollectionView as your ItemsSource. You then need to specify several GroupDescriptions for the ListCollectionView's GroupDescriptions property.
To define how these groups look like, you might have a look at this SO post: How do I group items in a WPF ListView. Other blog posts of interest might be: Bea Stollnitz: How can I do custom Grouping?, and Bea Stollnitz: How do I sort groups of data items?
In your scenario you would use the title of your email conversation as the group header, and maybe some additional data.

How to display in each ListBoxItem textblocks with binding to a filelds of a different tables

Greetings to all and sorry for my English!
I have a ListBox, it's ItemsSource = myClientsList.DefaultView. The Items of ListBox have a template (ControlTemplate), that is defined in a in a separate resource file.
Every Item contains a little TextBlock's, Text -property of each have a binding to fields of my Object myClientsList.
I need to add in a this item template more TexBlock's and each of them must have binding to fields of another my class myOrdersList. - (So I wish to view on each line of ListBox information from different tables of my database - this is a question).
Problem in that that ListBox's ItemsSource have a link to object myClientsList and I cann't set myOrderList to ItemSource of same ListBox. So i must find a way to specify TextBlock.DataContext wich inside ControlTemplate or how it's possible to solve this problem in another way?
p.s. I'm a new in .Net and WPF and probably have a mistakes in my explanation - sorry for it.
It sounds like you have a DataGrid type of display and want to add more columns in order to display the order information for a given client. If this is the case, you are going to have to do a couple of things. First, you will need to create a composite object that stores information for both entities into a single object (so each row of your control has all the data it needs to display). Secondly, I would recommend using an actual DataGrid control to display rows instead of templating a ListBoxItem. The ListView with a GridView built into the framework isn't great, so I would recommend the WPFToolkit's DataGrid for a free option.
There are two issues here, if I've understood the question: how do you create a single collection containing both Clients and Orders, and how do you display Clients and Orders in different ways within the same ListBox?
Regarding the first, you can do this using a CompositeCollection.
Regarding the second, define two DataTemplates instead of a ControlTemplate. As the key of each DataTemplate, use the type of the object it is going to present e.g.
<DataTemplate x:Key="{x:Type local:Client}">
Alternatively, use ItemsControl.ItemTemplateSelector to explicitly point at different DataTemplates depending on the type of item. Ot if you really have to use ControlTemplates, check out ItemsControl.ItemContainerStyleSelector.

Resources