An excerpt from this message thread on Silverlight.net follows:
TabControl and Databinding is a sore point for a while now. You can show your support in fixing it on this codeplex bug:
http://silverlight.codeplex.com/WorkItem/View.aspx?WorkItemId=3604
We're planning on overhauling TabControl for the Silverlight vNext release.
Sincerely,
--
Justin Angel,
Blog @ http://silverlight.net/blogs/JustinAngel
Twitter @ http://twitter.com/JustinAngel
The problem reveals itself in the PRISM View Injection QuickStart:
Since PRISM has a TabcontrolRegionAdapter for Silverlight we have a hook into the problem (for a work-around). Excerpt from documentation on the BootStrapper follows:
Conditional compiling is used to register the TabControlRegionAdapter only for Silverlight. This is because when you add an item in a TabControl control in WPF, this item is wrapped inside a TabItem type. This is not applicable for Silverlight, where you must manually wrap the item into the TabItem; because of that, the TabControlRegionAdapter adapter was modified to both adapt a region to the TabControl control and to automatically add this wrapping.
PRISM users can update the TabControlRegionAdapter.cs, in the Composite.Presentation project, as follows:
private static TabItem PrepareContainerForItem(object item, DependencyObject parent)
{
TabItem container = item as TabItem;
if (container == null)
{
container = new TabItem();
container.Content = item;
container.DataContext = GetDataContext(item);
container.Style = GetItemContainerStyle(parent);
container.SetValue(IsGeneratedProperty, true);
// BillKrat.2009.08.06 - SL3 Template binding bug workaround
if (container.Header != null
&& container.Header.ToString().Contains("Binding:"))
{
PropertyInfo modelProperty = null;
// Strip "Binding:" from the header - leaving model property
string modelPropName = container.Header.ToString().Replace("Binding:", "");
// Get model properties and search for the property name provided
PropertyInfo[] propInfo = container.DataContext.GetType().GetProperties();
if (propInfo != null)
modelProperty =
propInfo.FirstOrDefault(p => p.Name.ToString() == modelPropName);
// If found then update the header with the value
if (modelProperty != null)
container.Header = modelProperty.GetValue(modelProperty, null);
}
}
return container;
}
Instead of using Value="{Binding HeaderInfo}", which won't work under SL3, you can use "Binding:HeaderInfo" which will be processed by the above method. (note: Header will be set/available when the container.Style property is set above). An example follows:
<Regions:TabControlRegionAdapter.ItemContainerStyle>
<Style TargetType="Controls:TabItem">
<Setter Property="Header" Value="Binding:HeaderInfo"/>
</Style>
</Regions:TabControlRegionAdapter.ItemContainerStyle>
Until the Silverlight Toolkit team resolves the issue this can serve as a work-around. With some work it could be made more dynamic but this is a good starting point.
The model being used follows:
namespace UIComposition.Modules.Project
{
public class ProjectsListPresentationModel
{
public ObservableCollection<BusinessEntities.Project> Projects { get; set; }
public static string HeaderInfo
{
get { return "Current Projects"; }
}
}
}
EDITED - a better solution was provided on the following link. Although I haven't tested it yet I was impressed that it resolves the problem with one line of code - my kind of fix! I found the above to be a great learning exercise in the power of styles so I leave it intact as is.
PRISM User forum addressing the issue HERE
Tags:
bugfix,
silverlight,
sl3,
compositewpf,
prism
Categories:
CompositeWPF