Silverlight 5 + Prism:TabControlRegionAdapter - silverlight

I had a View using a TabControl with a prism:TabControlRegionAdapter
<sdk:TabControl Grid.Row="1" AutomationProperties.AutomationId="GUID" Margin="8,8,12,12"
prism:RegionManager.RegionName="GUID_REG_NAME"
prism:RegionManager.RegionContext="{Binding CurrentSelectedItem}" Name="TabControl1" >
<prism:TabControlRegionAdapter.ItemContainerStyle>
<Style TargetType="sdk:TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<!--Display the child view name on the tab header-->
<DataTemplate>
<TextBlock Text="{Binding ViewName}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</prism:TabControlRegionAdapter.ItemContainerStyle>
</sdk:TabControl>
Everything worked fine as long as I targeted Silverlight 4.
I got the Silverlight 5 beta and changed the project's target version to SL 5.
Now the view won't compile with error:
The property 'ItemContainerStyle' does not exist on the type 'TabControl' in the XML namespace 'http://www.codeplex.com/prism'
Anyone else got this error?
Any ideas about the causes/how to fix it?

I had the same issue. I put the tab style into the resources section of the xaml and used the following code-behind:
TabControlRegionAdapter.SetItemContainerStyle(TabControl1, Resources["TabControl1ItemStyle"] as Style);

Related

WPF - styling RadioButton as ToggleButton works, but shows error in VS

Working to create a top level menu in WPF, I used the trick of styling a RadioButton as a ToggleButton in order to get the "only one selected" effect. Like this:
<ItemsControl ItemsSource="{Binding ViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Key.Name}" GroupName="MenuButtonGroup"
Style="{StaticResource {x:Type ToggleButton}}" >
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
It works beautifully, and does just what I expect. But Visual Studio registers it as an error.
The Style property is underlined in blue and the description given is The resource "{x:Type ToggleButton}" could not be resolved.
It all looks above board but having this sat on my error list in Visual Stuido is hugely irritating. Any idea how to resolve it?
EDIT: Just found this question -
The resource could not be resolved (VS 2010 RC)
Which suggests it's a VS error. Anyone confirm this, or know of a fix? Wherever the problem is, it's still really annoying!
You could move the style to a Resources collection e.g.
<Window.Resources>
<Style x:Key="MyStyle" TargetType="{x:Type RadioButton}" BasedOn="{StaticResource {x:Type ToggleButton}}" />
</Window.Resources>
and then reference that style:
<RadioButton Content="{Binding Key.Name}" GroupName="MenuButtonGroup"
Style="{StaticResource MyStyle}" />

WPF MVVM - What's the most correct way to fire events within TreeViewItem

I'm currently using this extension to set specific events which handle data in the ViewModel... Example:
<swi:Interaction.Triggers>
<swi:EventTrigger EventName="Click">
<esi:CallDataMethod Method="SaveRevision_Clicked"/>
</swi:EventTrigger>
</swi:Interaction.Triggers>
Where esi and swi are:
xmlns:esi="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"
xmlns:swi="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
But what I want to set an event for a TreeViewItem? I don't have direct access to them, do I?
EDIT: I'm actually using ItemContainerStyle,
<Style x:Key="FolderView" TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" >
<StackPanel Orientation="Horizontal">
<Image Name="img"
Width="20"
Height="20"
Stretch="UniformToFill"
Source="Images/hdicon.png"/>
<TextBlock Text="{Binding FolderName}" Margin="5,0" />
</StackPanel>
</HierarchicalDataTemplate>
</Setter.Value>
</Setter>
</Style>
But I can't place my event in there. Where should I put these lines?
<swi:Interaction.Triggers>
<swi:EventTrigger EventName="Expanded">
<esi:CallDataMethod Method="Expand"/>
</swi:EventTrigger>
</swi:Interaction.Triggers>
Thanks in advance!
You need to use TreeView.ItemContainerStyle to achive this, here are couple of implementations which may help:
Strange Behaviour WPF TreeView ItemContainerStyle and ItemTemplate
WPF Double Click TreeviewItem Child Node

WPF - Freezable in a style of a button not inheriting DataContext

I am modeling an attached command pattern after the AttachedCommandBehavior library here. My button looks like this:
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="vms:Attached.Behaviors">
<Setter.Value>
<vms:Behaviors>
<vms:Behavior Event="Click"
Command="{Binding ClickCommand}" />
</vms:Behaviors>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
Everything works great, but when the setter on the Behavior is executed, the Command is null.
Behavior is a Freezable, and Behaviors is a FreezableCollection<Behavior>. It just doesn't seem to be inheriting the DataContext from the Button.
On the other hand, this works correctly:
<Button>
<vms:Attached.Behaviors>
<vms:Behavior Event="Click" Command="{Binding ClickCommand}" />
</vms:Attached.Behaviors>
</Button>
Unfortunately I can't do it this way, because I need to target generated ListViewItems using ItemContainerStyle.
Is there some way to get the DataContext in the Style?
The Attached Command Behavior library is the germ of the idea that became Blend Behaviors. The Blend Behaviors are much more powerful and standardized and so I recommend you switch to using them. But whether you are using Attached Command Behavior or Blend Behaviors, the problem is essential the same: they don't work as expected when trying to set them using a style. I've solved this problem for Blend Behaviors with full support for binding in this StackOverflow answer:
How to add a Blend Behavior in a Style Setter
Without testing it, I guess you have to move the ACB behavior to a resource marked with x:Shared="False" in order to get the binding to work.
I had the same problem, and using RelativeSource did the trick. I'll show you my before and after code...
Before: (This DIDN'T work)
<DataTemplate x:Key="MenuNodeWithChildrenTemplate">
<StackPanel Orientation="Horizontal"
behaviors:EventCommand.CommandToRun="{Binding OpenMenuItem}"
behaviors:EventCommand.EventName="MouseLeftButtonUp">
<Label Content="{Binding Title}"/>
<Label Content="{Binding Description}"/>
</StackPanel>
</DataTemplate>
After: (This DOES work)
<DataTemplate x:Key="MenuNodeWithChildrenTemplate">
<StackPanel Orientation="Horizontal"
behaviors:EventCommand.CommandToRun="{Binding Path=DataContext.OpenMenuItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"
behaviors:EventCommand.EventName="MouseLeftButtonUp">
<Label Content="{Binding Title}"/>
<Label Content="{Binding Description}"/>
</StackPanel>
</DataTemplate>
You'll obviously have to tweak the parameters of the Relative Source to your specific situation. It seems that, for whatever reason, attached properties don't inherit the data context, so you have to tell if how to.

WP7 Bing Maps Pushpin template with image doesn't show up

My ultimate goal is to have pushpins with custom images on a Bing Map in a WP7 app. I have created a control template and a map with a pushpin. Right now, I can get the default pushpins to show up, but nothing shows when I try to template it. Here's what I have right now:
<phone:PhoneApplicationPage.Resources>
<ControlTemplate x:Key="PushpinControlTemplate" TargetType="my:Pushpin">
<Image Source="/Images/Pins/pin.png" />
</ControlTemplate>
</phone:PhoneApplicationPage.Resources>
<my:Map Name="mapMain" CredentialsProvider="CredKey">
<my:Pushpin/>
</my:Map>
If I apply the PushpinControl template nothing shows up:
<my:Pushpin Template="{StaticResource BoaPushpinControlTemplate}" />
If I remove the template, it shows the default black shape.
I must be doing my template incorrectly, but I don't know what the problem is. Can I not have an image in the ControlTemplate?
If you arent using ItemSource binding on the Map then use simple content control approach
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
Or if you dynamically populating the push-pins use the below approach
<maps:Map x:Name="map" >
<maps:MapItemsControl ItemsSource="{Binding Collection}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Location="{Binding Location}">
<Image Source="/Images/Pins/pin.png" />
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
Even though this thread is a little bit old I'm going to post my suggestion:
Try out this link Working with Pushpins, it is working for me (create a new style and use it in pushpin declaration)
(App.xaml, do not forget the namespace!)
xmlns:m="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps" >
<Application.Resources>
<Style TargetType="m:Pushpin" x:Key="PushpinStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="m:Pushpin">
<Image Width="24" Height="24" Source="path_to_pic" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
(in the xaml there the map is)
<Grid x:Name="LayoutRoot" Background="Transparent">
<m:Map x:Name="Map" Mode="Aerial"
CredentialsProvider="CredKey">
<m:MapItemsControl x:Name="Content">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<m:Pushpin Location="{Binding Location}" Style="{StaticResource PushpinStyle}" />
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:Map>
</Grid>
If this isn't working check if the Build Action of your picture is set to content.
Took me a while to figure this out, so i hope i could help someone, despite the fact that this thread is old. ;)

How can I trigger this Error Template?

Below is a template that works from a binding perspective, but the error template doesn't show, and without an AdornedElementPlaceholder the result looks a bit garish.
My view models implement IDataErrorInfo, and normally I would trigger the error template by having ValidatesOnError=True as part of my binding. This particular view model is display only, so the IDataErrorInfo indexer is never invoked. I do have a number of useful properties related to validation though, including a boolean IsValid property as well as IDataErrorInfo.Error, both of which properly respond to the view model being invalid.
Should I translate the error to a ValidationResult and trigger it that way? Or is there something easier?
Cheers,
Berryl
current template
<!-- FooterViewModel DataTemplate -->
<DataTemplate DataType="{x:Type model:FooterViewModel}">
<Label x:Name="lblTotalTime"
Style="{StaticResource FooterStyle}"
Content="{Binding TotalTime, Converter={StaticResource TotalAmountConv}}" >
<Label.ToolTip>
<TextBlock Text="{Binding FeedbackMessage}" ></TextBlock>
</Label.ToolTip>
<Validation.ErrorTemplate>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right" Text=" *"
Foreground="Red"
FontWeight="Bold" FontSize="16"
/>
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="placeholder"></AdornedElementPlaceholder>
</Border>
</DockPanel>
</ControlTemplate>
</Validation.ErrorTemplate>
</Label>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsValid}" Value="False">
<Setter TargetName="lblTotalTime" Property="Control.BorderBrush" Value="Red"/>
<Setter TargetName="lblTotalTime" Property="Control.BorderThickness" Value="1"/>
<Setter TargetName="lblTotalTime" Property="Control.Background" Value="LightYellow"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
UPDATE
Ok, I am getting IDataErrorInfo to kick in just by changing my binding to include ValidatesOnErrors, BUT the error template still does not show up.
Here is the binding
<ItemsControl
ItemsSource="{Binding Path=FooterViewModels, Mode=OneWay, ValidatesOnDataErrors=True}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
By default, the validation is only run when the Source of the binding is updated. In your ItemsControl.ItemsSource binding the Sources is your FooterViewsModels, which obviously will never be updated (because you have Mode=OneWay).
You can use the DataErrorValidationRule.ValidatesOnTargetUpdated to run the validation when the target is updated as well. The link gives an example.
Keep in mind that the Binding.ValidatesOnDataErrors property is is just a short cut for adding an instance of DataErrorValidationRule to the Binding.ValidationRules collection.
Finally, the control that the binding is defined one will have the Validation.Errors. In your case, that is the ItemsControl, not the items inside it. So, I believe you need to add the DataErrorValidationRule to your Label.Content binding. Or you need to define your ErrorTemplate on the ItemsControl, depending on what you are going for.

Resources