DataTemplate in ResourceDictionary and Events - silverlight

in my Silverlight 4 application, I have a listbox for which I created a nice DataTemplate. This DataTemplate contains some buttons, for which I want to handle events. So I assigned the event on the template:
<DataTemplate>
<Grid>
<Button x:Name="myB" Click="myB_Click" />
</Grid>
</DataTemplate>
In the UserControl that contains the listbox that uses this template I have the eventhandler that handles the myB_Click.
As long I have the template assigned directly within the listbox, everything works fine:
<ListBox ...>
<ListBox.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But when I outsource the DataTemplate to a ResourceDirectory, I get a runtime parser-error when adding an item to the listbox
Kategorie: ParserError
Message:
Error assigning to Property
'System.Windows.Controls.Button.Click'.
Any idea, what might cause this?
Thanks in advance,
Frank

if you put it in a resource dictionary then it can't find the event handler since your resource dictionary doesn't have code behind.
either you (a) don't put that part in the ResourceDictionary and keep it in your xaml
or (b) add code behind to your resource dictionary

Related

WPF listbox OO data template

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>

Switch View based on selected TreeViewItem

I have a Shell.xaml file which contains two other UserControls. On the left is my TreeView and on the right is a detail screen.
I want the detailscreen to be switchable based on a selected TreeViewItem. I know this can be achieved by using DataTemplates, because I've done it with simple button clicks and using the <ContentControl Content="{Binding CurrentDetailViewModel}"> tag to accomplish this, but I have no idea how to accomplish this based on a selected TreeViewItem. I also have a separate ViewModel class for my UserControl which holds my TreeView and a separate for each detail screen.
I've been using Josh Smith's tutorial on TreeViews: http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx
So I also do use the TreeViewItemViewModel.cs class of his.
Could someone shed some light onto this?
Thanks,
Grant
If both the treeview and the details are displaying the same object (i.e the ItemsSource of the treeview contains the objects that you want to data template in the custom control) then you should be able to set a property on an underlying ViewModel that both controls share and have the custom control display something relevant with data templates.
for example, in the ViewModel:
object TreeViewSelectedItem
{
get{ return _treeViewSelectedItem;}
set {_treeViewSelectedItem = value; NotifyPropertyChanged("TreeViewSelectedItem");}
}
Treeview xaml
<TreeView ... SelectedItem={Binding TreeViewSelectedItem Mode=OneWayToSource}".../>
custom control xaml
<UserControl>
<Control.Resources>
<DataTemplate DataType="{x:Type Plane}">
....
</DataTemplate>
<DataTemplate DataType="{x:Type Train}">
....
</DataTemplate>
<DataTemplate DataType="{x:Type Automobile}">
....
</DataTemplate>
</Control.Resources>
<ContentControl Content={Binding TreeViewSelectedItem}"/>
</Usercontrol>

ElementName not working when assigning DataTemplate from code behind?

I am trying to access Control using ElementName from DataTemplate that is used in different UserControl (Resources) than defined (in xaml).
Imagine this situation:
MyUserControl.xaml with following DataTemplate in resources:
<UserControl.Resources>
<DataTemplate x:Key="SomeTemplate">
<TextBlock Text="{Binding Text, ElementName=TextElement}"/>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock x:Name="TextElement" Text="IT WORKS! (not...)"/>
</Grid>
</UserControl>
MyUserControlWrapper.xaml
<ContentPresenter x:Name="ContentPresenter" Content="{Binding SomeContent}"/>
and in code behind of MyUserControlWrapper.xaml i set ContentTemplate of ContentPresenter from MyUserControl.xaml:
something like:
ContentPresenter.ContentTemplate = (DataTemplate)childView.Resources["SomeTemplate"];
Is it possible to use ElementName from resources that are defined outside UserControl?
How DataTemplate searches for ElementName in same UserControl then? Maybe its possible to set something like DataContext for DataTemplate itself for ElementName to work, without messing with DataContext that is sent to controls used inside Template?
You need to review the concepts related to Namescopes.
Briefly names are scoped at the point where a Xaml resources are loaded. For example each UserControl will each load their own Xaml and therefore have their own namescope. In your case you asking MyUserControlWrapper to find a name that its LoadComponent has not seen.
Maybe you can just walk up the VisualTree using RelativeSource and FindAncestor?
There is a nice presentation of different binding variants here:
http://www.wpfwiki.com/Default.aspx?Page=WPF%20Q5.3&AspxAutoDetectCookieSupport=1

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