WPF listbox OO data template - wpf

This is a basic question but I'm just coming back to WPF after a long break and can't remember how to do this. I've tried looking around but can't find exactly the answer I'm looking for.
I have a Listbox control that I want to bind to a List<TradeViewModel> collection. I want the ListBoxItems to pick up that the items are of type TradeViewModel and based on that, to use a custom data template including a checkbox that is bound to TradeViewModel.IsChecked and for the text of the row to be TradeViewModel.TradeId.
I have created the ViewModel class with exposed dependency properties and INotifyPropertyChanged but it's how to hook up the XAML and data templates that I can't quite remember how to do.
Can someone please help me with a quick example?
Thanks!

<ListBox ItemsSource="{Binding YourList}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid> <!-- Or whatever -->
<CheckBox IsChecked="{Binding IsChecked}"/>
<!-- Other UI Elements here -->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Related

CheckedListBox in WPF

We are working on an application using the MVVM architectural style (WPF) and facing an issue.
Before using WPF we have worked with WinForms and we used CheckedListBox. But now we are unable to find such control in WPF.
We are also using Infragistic toolkit.
Please provide any kind of help. Any lead will be appreciable.
You can take a Listbox and give it a Template with a Checkbox in.
Something like:
<ListBox ItemsSource="{Binding MyItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected}" Content="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
This looks like this:
Edit: The Items must have a Property "IsSelected" or you have to Wrap them in a SelectableItem helper class, which holds the original Item and a IsSelected Property.

How to expose ItemTemplate and ContentTemplate from a UserControl

I have written a Well control, similar to the Visual Studio editor tabs so that a user can have multiple documents open and can see one or more at a time. It is derived from a UserControl and exposes an ObservableCollection of OpenDocuments that binds to the ViewModel. If I were to implement this as a simple TabControl, then this would be how it would look:
<TabControl
Grid.Row="1"
Grid.Column="1"
ItemsSource="{Binding OpenDocuments}"
SelectedItem="{Binding SelectedTab, Mode=TwoWay}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<vw:DocumentView />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
This gives me Name in the tabitem header and the DocumentView (another user control in the Content area).
My control has a ContentTemplate but it is of course representing the whole of the control so all I get to see is the DocumentView. My control doesn't have an ItemTemplate.
How do I expose an ItemTemplate and ContentTemplate?
Andrew
EDIT -------------------------------------------------------------------------
Thanks for the replies. It looks like this:
A user can have one or more document wells holding one or more tabs. All the consumer has access to is the list of visible tabs and the currently selected tabitem.
Notice that the tabs are all empty! I don't understand how to specify the ContentTemplate for the <vw:DocumentView> in the same way as the TabControl example above.
Andrew
I am a little confused on exactly what your control looks like but here is what I think you are after.
If your control can inherit from ItemsControl you will get the ItemTemplate property already defined for you. All you have to do in your control template is to Template bind the ItemsControl property to the correct place in the template.
The same applies for the ContentTemplate. If you have the a ContentTemplate property already defined for you control you just need to Template Bind it to the correct place in the control.
It would look something like this
Control Consumer
<MyControlNamespace:MyControl ContentTemplate="{StaticResource MyContentTemplate}" ItemTemplate="{StaticResource MyItemTemplate}" />
Implementation of "MyControl" from above (totally pseudo code)
<MyControl>
<ItemsPresenter ItemTemplate="{TemplateBinding ItemTemplate}" />
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" />
</MyControl>
Again, my example doesn't fully make sense but I am not sure what your control looks like and not entirely sure what you are asking, but hopefully this helps.

UserControl as Content for HeaderedContentControl.HeaderTemplate

I have a UserControl that I have successfully been using as a header for presentations that involve a list which can be headered, using the xaml below:
<DockPanel >
<uc:ListSubjectHeader Subject="{Binding DisplayName}"
AddNewItemCommand="{Binding AddCommand}"
ImageSource="..." />
<!-- other controls -->
</DockPanel>
I would like to use this same control in another presentation where it would be the content for the header in a HeaderedContentControl, and came up with this xaml to do that:
<HeaderedContentControl Content="{Binding Path=DetailViewDepartment}" >
<HeaderedContentControl.HeaderTemplate>
<DataTemplate DataType="{x:Type vm:DepartmentSelectionViewModel}">
<uc:ListSubjectHeader Subject="{Binding DisplayName}" ... />
</DataTemplate>
</HeaderedContentControl.HeaderTemplate>
</HeaderedContentControl>
The visual elements show up the way I want them to, but data does not. I should note that I am using the same view model (vm:DepartmentSelectionViewModel) in a different control's DataTemplate in the same presentation, which I asked as a different question here. If you know the answer to this one you likely know the answer to that one too.
How can I fix this?
Cheers,
Berryl
The HeaderTemplate applies to the object in the Header property, not Content. Content uses the ContentTemplate, just like in the normal ContentControl.

Use a user control as a DataTemplate within a WPF application

I am trying to create a user control within a WPF application that will serve as a DataTemplate for a ListBoxItem. The user control a grid with 4 TextBlocks. This control also contains other shapes and images more for visual aid than anything so I am omitting them from the code in this question for clarity.
When I drop the user control on my mainwindow.xaml I can see the control and the properly bound fields point to the first record in the datasource. What I want to do is have this control render repeatedly within either a listbox or a wrap panel for each record within the database.
Can anyone provide me with a pointer or sample of how to have a user control render as a DataTemplate within the ListBox control/other panel.
Up to this point I have tried the following with no avail:
Thanks in advance for any tips.
<!--within Window.Resource -->
<DataTemplate x:Key="myActivity">
<local:ucActivityItm /> <!--usercontrol -->
</DataTemplate>
<!-- Listbox within the window -->
<ListBox HorizontalAlignment="Stretch" ItemTemplate="{DynamicResource myActivity}" VerticalAlignment="Stretch">
<ListBoxItem>
<!-- control also added for testing to ensure it rendered out-->
<local:ucActivityItm />
</ListBoxItem>
</ListBox>
That DataTemplate isn't actually being assigned to your ListBox. There's three ways:
1: Replace the template in the Resources section with
<ListBox.ItemTemplate>
<DataTemplate>
<local:ucActivityItm />
</DataTemplate>
</ListBox.ItemTemplate>
in the ListBox.
2: Somewhat related:
<ListBox ... ItemTemplate="{StaticResource myActivity}">
3: Set the DataType parameter of the DataTemplate above to whatever the content of your ListBox is.
<DataTemplate x:Key="myActivity" DataType="{x:Type ...}">
I usually just do the first, but any should work.

How to bind items of a TabControl to an observable collection in wpf?

What is the simplest example of binding the items of a TabControl to an ObservableCollection?
Each tab's content will have unique data, and indeed this data will have observableCollections of its own bound to the items components.
Currently I have a user control, which I would like to set as the content of each tab as soon as it is created. I also need to dynamically set the datacontext of this new user control when the tab is created. So, essentially, I would like the tabcontrol's observablecollection contain modelviews that map to the data in each tab.
On top of that, I need to do all this without violating MVVM in WPF! Any help?
Much appreciated!
Basic example :
<Window.Resources>
<DataTemplate x:Key="templateForTheContent" DataType="{x:Type vm:TheViewModelType}">
<v:YourUserControl/>
</DataTemplate>
<DataTemplate x:Key="templateForTheHeader" DataType="{x:Type vm:TheViewModelType}">
<TextBlock Text="{Binding ThePropertyToDisplayInTheHeader}"/>
</DataTemplate>
</Window.Resources>
...
<TabControl ItemsSource="{Binding YourCollection}"
ContentTemplate="{StaticResource templateForTheContent}"
ItemTemplate="{StaticResource templateForTheHeader}">
</TabControl>

Resources