ContentControl Template through Property - wpf

I have a Usercontrol with a ControlTemplate DependencyProperty (named MyItemTemplate).
public ControlTemplate MyContentControl
{
get { return (ControlTemplate)GetValue(MyContentControlProperty); }
set { SetValue(MyContentControlProperty, value); }
}
public static readonly DependencyProperty MyContentControlProperty =
DependencyProperty.Register("MyContentControl", typeof(ControlTemplate), typeof(MyScroll),
new PropertyMetadata(new ControlTemplate()));
In the xaml of my UserControl I want to use the "MyItemTemplate" as a template for a ContentControl like that :
<ContentControl x:Name="MyContentControl" Template="{Binding MyItemTemplate}" />
I know that the Template="{Binding MyItemTemplate}" is wrong, but I wonder how to do it...
Thanks

You can use a RelativeSource binding to reference a custom DependencyProperty on your UserControl
<ContentControl Template="{Binding
RelativeSource={RelativeSource AncestorType={x:Type local:MyUserControl}},
Path=MyItemTemplate}" />
Edit
If you're working in Silverlight 4.0 or lower, which doesn't support RelativeSource bindings, then give your UserControl tag a Name and use an ElementName binding
<UserControl x:Name="MyUserControl" ...>
<ContentControl Template="{Binding ElementName=MyUserControl, Path=MyItemTemplate}" />
</UserControl>

Have your template as a static resource (defined in your XAML somewhere).
<DataTemplate x:Key="DetailedTemplate">
<Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige">
<StackPanel Orientation="Horizontal">
<Image Margin="10" Width="250" Height="200" Stretch="Fill" Source="{Binding Path=ImageHref}">
<Image.BitmapEffect>
<DropShadowBitmapEffect />
</Image.BitmapEffect>
</Image>
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<TextBlock FontSize="25" Foreground="Goldenrod" Text="{Binding Path=ImageName}" />
<Label Content="{Binding Path=ImageRating,Converter={StaticResource RatingConverter}}" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
<DataTemplate x:Key="SimpleTemplate">
<Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="5" Background="Beige">
<StackPanel HorizontalAlignment="Center">
<Image Margin="10" Width="250" Height="200" Stretch="Fill" Source="{Binding Path=ImageHref}">
<Image.BitmapEffect>
<DropShadowBitmapEffect />
</Image.BitmapEffect>
</Image>
</StackPanel>
</Border>
</DataTemplate>
For example, in XAML:
<ListBox x:Name="lbResults" Grid.Row="1" Grid.Column="0" Height="240"
HorizontalContentAlignment="Stretch" ItemsSource="{StaticResource FavoriteImages}"
ItemTemplate="{StaticResource SimpleTemplate}" />
Then in the code behind something like:
//pull the detailed template from resources, identified by the DetailedTemplate key
DataTemplate detail = this.FindResource("DetailedTemplate") as DataTemplate;
lbResults.ItemTemplate = detail;
and
//pull the summary template from resources, identified by the SimpleTemplate key
DataTemplate summary = this.FindResource("SimpleTemplate") as DataTemplate;
lbResults.ItemTemplate = summary;

Although the best answer is Rachel's, here are some alternatives.
If this logic is not critical, you'd better put the template into resources and get it using StaticResource:
<UserControl>
<UserControl.Resources>
<ControlTemplate x:Key="template">
...
</ControlTemplate>
</UserControl.Resources>
<ContentControl Template="{StaticResource template}"/>
</UserControl>
If you still need to set it from the UserControl's property, you may either define a change callback.
XAML:
<UserControl>
<ContentControl x:Name="contentControl"/>
</UserControl>
Code-behind:
public ControlTemplate MyContentControl
{
get { return (ControlTemplate)GetValue(MyContentControlProperty); }
set { SetValue(MyContentControlProperty, value); }
}
public static readonly DependencyProperty MyContentControlProperty =
DependencyProperty.Register("MyContentControl", typeof(ControlTemplate), typeof(MyScroll), new PropertyMetadata(null, OnMyContentControlChanged));
static void OnMyContentControlChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var userControl = (MyScroll)sender;
userControl.contentControl.Template = e.NewValue as ControlTemplate;
}
And the last option is using a Custom Control.
Code:
public class MyScroll : SomeParentControl
{
public MyScroll()
{
this.DefaultStyleKey = typeof(MyScroll);
}
public ControlTemplate MyContentControl
{
get { return (ControlTemplate)GetValue(MyContentControlProperty); }
set { SetValue(MyContentControlProperty, value); }
}
public static readonly DependencyProperty MyContentControlProperty =
DependencyProperty.Register("MyContentControl", typeof(ControlTemplate), typeof(MyScroll), new PropertyMetadata(null));
}
The template:
<!-- This is a template for what have been your UserControl -->
<ControlTemplate TargetType="{x:Type someNameSpaceAlias:MyScroll}">
<!-- And this is the 'MyContentControl' -->
<ContentControl Template="{TemplateBinding MyContentControl}"/>
</ControlTemplate>

Related

Bind header and content dynamically to expander

Firstly I see the type for Header and content for the expander, it says the type is object. I have a user control with name CommonExpanderUserControl as follows,
xaml:
<uwpControls:Expander Header="{Binding HeaderContent}" Content="{Binding MainContent}">
</uwpControls:Expander>
In xaml.cs (DataContext is set to this)
public static readonly DependencyProperty HeaderContentProperty =
DependencyProperty.Register("HeaderContent", typeof(object), typeof(CommonExpanderUserControl), new
PropertyMetadata(null));
public object HeaderContent
{
get { return (object)GetValue(HeaderContentProperty); }
set { SetValue(HeaderContentProperty, value); }
}
public static readonly DependencyProperty MainContentProperty =
DependencyProperty.Register("MainContent", typeof(ContentControl), typeof(CommonExpanderUserControl), new
PropertyMetadata(null));
public ContentControl MainContent
{
get { return (ContentControl)GetValue(MainContentProperty); }
set { SetValue(MainContentProperty, value); }
}
Now I am using this UserControl somewhere outside as follows,
<UserControl.Resources>
<ContentControl x:Key="Header">
<Grid x:Name="ExpanderHeaderGrid" HorizontalAlignment="Stretch" Padding="0" Margin="0"
Background="{Binding LisSharedSettings.ChangeHeaderColor,Converter={StaticResource BoolToSolidBrushConverter}}">
<TextBlock x:Name="TextBlockLisSharedSettingsTitle"
x:Uid="/Application.GlobalizationLibrary/Resources/InstrumentSettingsViewLisSettingsTextBlockTitle"
Style="{StaticResource TextBlockStyleSectionHeader}"/>
</Grid>
</ContentControl>
<ContentControl x:Key="Body">
Some content here.
</ContentControl>
</UserControl.Resources>
<Grid>
<local:CommonExpanderUserControl HeaderContent="{StaticResource Header}" MainContent="{StaticResource Body}"/>
</Grid>
Binding Content control like that simply doesn't work. If I remove the MainContent binding and bind only the Header, it says object reference not set to an instance of an object. Please help.
The problem occurs StaticResource binding, we could not bind header with control by StaticResource. And for the scenario the better way is bind HeaderTemplate and send the data source to the header property like the following.
<UserControl.Resources>
<DataTemplate x:Key="HeaderTemplate">
<Grid
x:Name="ExpanderHeaderGrid"
Margin="0"
Padding="0"
HorizontalAlignment="Stretch"
Background="Red"
>
<TextBlock x:Name="TextBlockLisSharedSettingsTitle" Text="{Binding}" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<uwpControls:Expander Header="hello" HeaderTemplate="{StaticResource HeaderTemplate}" />
</Grid>

Custom User Control not binding data [duplicate]

This question already has answers here:
Issue with DependencyProperty binding
(3 answers)
Datacontext conflicts
(1 answer)
How to correctly bind to a dependency property of a usercontrol in a MVVM framework
(4 answers)
Closed 5 years ago.
I've created a user control that have a label and textbox.
i added two DependencyProperties (Text and Label) and bind them to textbox.text and label.content.
however, i'm not able to see the text of textbox.
in the main window, when i'm not binding to any element the label is shown but if i binding the element is not shown. the textbox not showing either way.
here's the xaml:
<UserControl x:Class="TestNewLabeltextbox.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Horizontal" Background="White" FlowDirection="RightToLeft">
<Label x:Name="lbl" Content="{Binding Label, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="100" HorizontalAlignment="Left" Background="blue">
<Label.Style>
<Style TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<StackPanel Orientation="Horizontal">
<Border Background="Blue" Width="200" BorderThickness="0,0,0,0">
<StackPanel Orientation="Horizontal">
<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="0.0"
Color="#032A6B"
Direction="90"
Opacity="1"
ShadowDepth="1" />
</ContentPresenter.Effect>
</ContentPresenter>
</Viewbox>
</StackPanel>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Label.Style>
</Label>
<TextBox x:Name="txt" Text="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="120" HorizontalAlignment="Right">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Border CornerRadius="0,0,0,50" BorderBrush="Black" Background="White" BorderThickness="0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" RecognizesAccessKey="True" TextBlock.FontSize="14" TextBlock.Foreground="#FFFFFF" Margin="5">
<ContentPresenter.Effect>
<DropShadowEffect BlurRadius="0.0"
Color="#032A6B"
Direction="90"
Opacity="1"
ShadowDepth="1" />
</ContentPresenter.Effect>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
</StackPanel>
Here'sUserControl1.cs:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
this.DataContext = this;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
public string Label
{
get { return (string)this.GetValue(LabelProperty); }
set { this.SetValue(LabelProperty, value); }
}
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new PropertyMetadata(null));
public string Text
{
get { return (string)this.GetValue(TextProperty); }
set { this.SetValue(TextProperty, value); }
}
}
here's the window xaml + cs:
<Window x:Class="TestNewLabeltextbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:TestNewLabeltextbox"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Vertical" Height="150">
<controls:UserControl1 Text="hello" Height="50" Label="{Binding Hello, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<controls:UserControl1 Text="hello" Height="50" Label="world" />
<Label BorderBrush="Black" BorderThickness="2" Width="100" Height="50" Content="{Binding Hello, Mode=TwoWay}"/>
</StackPanel>
</Grid>
public partial class MainWindow : Window
{
ViewModel vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
vm.Hello = "555";
this.DataContext = vm;
}
}
viewmodel.cs
public class ViewModel : INotifyPropertyChanged
{
private string h = "Hello";
public string Hello
{
get
{
return h;
}
set
{
h = value;
NotifyPropertyChanged("Hello");
}
}
#region "PropertyChanged Event"
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Default Source of binding is DataContext. But your Label and Text dependency properties defined in the control rather than in view-model. Change binding of Label to
{Binding Path=Label, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}
and binding of TextBox to
{Binding Path=Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
Please read about Mode and UpdateSourceTrigger properties of Binding. It seems that you don't know how they work. Mode=TwoWay, UpdateSourceTrigger=PropertyChanged doesn't make any sense for Content property.

UserControl multiple datatemplate + templateselector

I need to show data inside a usercontrol in different ways depending on a flag.
To achieve this i tried the following, but using this control in the main view shows nothing.
<UserControl DataContext="**self**">
<UserControl.Resources>
<DataTemplate x:Key="mouseInputTemplate">
<TextBlock HorizontalAlignment="Center"><Run Text="{Binding Text}" /></TextBlock>
</DataTemplate>
<DataTemplate x:Key="touchInputTemplate">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Image Source="{Binding ImageUri}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Width="{Binding ImageWidth}" Height="{Binding ImageHeight}" />
<TextBlock HorizontalAlignment="Center"><Run Text="{Binding Text}" /></TextBlock>
</StackPanel>
</DataTemplate>
<local:InputModeDataTemplateSelector x:Key="inputModeTemplateSelector"
MouseInputModeTemplate="{StaticResource mouseInputTemplate}"
TouchInputModeTemplate="{StaticResource touchInputTemplate}" />
</UserControl.Resources>
<ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch" ContentTemplateSelector="{StaticResource inputModeTemplateSelector}" />
</UserControl>
What am i doing wrong?
Is there a better way to achieve that?
Thank to EdPlunkett and more research i found out it is better to
use a ContentPresenter here and instead of binding on DataContext=this bind like this (as alsways suggested when writing a UserControl)
DataContext="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type yourType}}}"
Code:
<UserControl.Resources>
<DataTemplate x:Key="touchInputTemplate">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Image Source="{Binding ImageUri}" Width="64" Height="64" />
<TextBlock HorizontalAlignment="Center" Text="{Binding Text}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="mouseInputTemplate">
<TextBlock HorizontalAlignment="Center" Text="{Binding Text}" />
</DataTemplate>
<local:InputModeDataTemplateSelector x:Key="inputModeTemplateSelector"
MouseInputModeTemplate="{StaticResource mouseInputTemplate}"
TouchInputModeTemplate="{StaticResource touchInputTemplate}" />
</UserControl.Resources>
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type yourType}}}">
<ContentPresenter Content="{Binding}" ContentTemplateSelector="{StaticResource inputModeTemplateSelector}">
</Grid>
Your ContentPresenter idea is the correct way to do it with a DataTemplateSelector, and I should have thought of it myself.
But here's yet another way to do it, which unlike my first answer, actually solves all the problems you're having:
XAML (in practice the Style would probably be defined in a separate ResourceDictionary):
<Window
x:Class="TestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestApplication"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="MainWindow" Height="350" Width="525"
>
<Window.Resources>
<Style TargetType="local:TestControl">
<Setter Property="Background" Value="Gainsboro" />
<Style.Triggers>
<!-- The 0 value for the InputMode enum is Mouse, so this will be the default. -->
<Trigger Property="InputMode" Value="Mouse">
<Setter Property="Background" Value="Wheat" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TestControl}">
<Grid Background="{TemplateBinding Background}">
<TextBlock HorizontalAlignment="Center"><Run Text="{TemplateBinding Text}" /></TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="InputMode" Value="Touch">
<Setter Property="Background" Value="LightSkyBlue" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TestControl}">
<Grid Background="{TemplateBinding Background}">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Image
Source="{TemplateBinding ImageUri}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="{TemplateBinding ImageWidth}"
Height="{TemplateBinding ImageHeight}"
/>
<TextBlock HorizontalAlignment="Center"><Run Text="{TemplateBinding Text}" /></TextBlock>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<local:TestControl
ImageHeight="100"
ImageWidth="100"
Text="This is the test control"
ImageUri="http://www.optimizeagency.com/wp-content/uploads/2015/09/GoogleLogo.jpg"
/>
</Grid>
</Window>
C#:
using System;
using System.Windows;
using System.Windows.Controls;
namespace TestApplication
{
class TestControl : Control
{
public TestControl()
{
// If input mode may change at runtime, you'll need an event that fires when that
// happens and updates this property.
// UIUtilities.GetInputMode() is just a stub in this example.
InputMode = UIUtilities.GetInputMode();
}
#region InputMode Property
public InputMode InputMode
{
get { return (InputMode)GetValue(InputModeProperty); }
set { SetValue(InputModeProperty, value); }
}
public static readonly DependencyProperty InputModeProperty =
DependencyProperty.Register("InputMode", typeof(InputMode), typeof(TestControl),
new PropertyMetadata(InputMode.Mouse));
#endregion InputMode Property
#region Text Property
public String Text
{
get { return (String)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(String), typeof(TestControl),
new PropertyMetadata(null));
#endregion Text Property
#region ImageUri Property
// The TemplateBinding in the template can't coerce a string to an
// ImageSource, so we have to make that happen elsewhere.
public ImageSource ImageUri
{
get { return (ImageSource)GetValue(ImageUriProperty); }
set { SetValue(ImageUriProperty, value); }
}
public static readonly DependencyProperty ImageUriProperty =
DependencyProperty.Register("ImageUri", typeof(ImageSource), typeof(TestControl),
new PropertyMetadata(null));
#endregion ImageUri Property
#region ImageHeight Property
public float ImageHeight
{
get { return (float)GetValue(ImageHeightProperty); }
set { SetValue(ImageHeightProperty, value); }
}
public static readonly DependencyProperty ImageHeightProperty =
DependencyProperty.Register("ImageHeight", typeof(float), typeof(TestControl),
new PropertyMetadata(float.NaN));
#endregion ImageHeight Property
#region ImageWidth Property
public float ImageWidth
{
get { return (float)GetValue(ImageWidthProperty); }
set { SetValue(ImageWidthProperty, value); }
}
public static readonly DependencyProperty ImageWidthProperty =
DependencyProperty.Register("ImageWidth", typeof(float), typeof(TestControl),
new PropertyMetadata(float.NaN));
#endregion ImageWidth Property
}
#region This stuff belongs in a different file
public static class UIUtilities
{
public static InputMode GetInputMode()
{
// Here you'd do whatever you're already doing to detect the input mode
return InputMode.Touch;
}
}
public enum InputMode
{
Mouse,
Touch
}
#endregion This stuff belongs in a different file
}

WPF Data Binding From UserControl

I want to bind 'SomeText' from my UserControl, into the Content of my Label.
I currently have a UserControl which just displays my 'SomeText'. The XAML, and Code Behind file can be seen below.
<UserControl x:Class="TabHeader.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="183" d:DesignWidth="235"
x:Name="uc">
<Grid>
<Label Height="43" HorizontalAlignment="Left" Margin="57,102,0,0" Name="textBlock1" Content="{Binding Path=SomeText, ElementName=uc}" VerticalAlignment="Top" Width="86" />
</Grid>
</UserControl>
namespace TabHeader
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
private string someText;
public UserControl1()
{
this.SomeText = "23";
InitializeComponent();
}
public string SomeText
{
get
{
return someText;
}
set
{
someText = value;
}
}
}
}
I then have my main XAML page where I have, a Tab Control within a Grid. I'm using a Style to generate two Labels within the Columns Header. I am able to pull through the Header field, but I am unable to pull through the controls field.
<Window x:Class="TabHeader.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vw="clr-namespace:TabHeader"
Title="MainWindow" Height="350" Width="525" Name="Tabs">
<Grid>
<TabControl Height="262" HorizontalAlignment="Left" Margin="47,26,0,0" Name="tabControl1" VerticalAlignment="Top" Width="366">
<TabControl.Resources>
<Style TargetType="TabItem" x:Key="tabItemHeaderStyle" >
<Setter Property="HeaderTemplate" >
<Setter.Value>
<DataTemplate DataType="{x:Type TabItem}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=Header, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}"/>
<Label Content="{Binding Path=SomeText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=vw:UserControl1}}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Style="{StaticResource tabItemHeaderStyle}" Header="TI 1" Name="tabItem1" Width="100">
<vw:UserControl1 x:Name="UserControl11"></vw:UserControl1>
</TabItem>
<TabItem Style="{StaticResource tabItemHeaderStyle}" Header="TI 2" Name="tabItem2">
</TabItem>
</TabControl>
</Grid>
</Window>
Any assistance with this would be greatly appreciated.
Cheers.
Edit 1
For anyone interested added my working code below, where I have used the DependencyProperty.
MainWindow.xaml
<Grid>
<TabControl Height="262" HorizontalAlignment="Left" Margin="47,26,0,0" Name="tabControl1" VerticalAlignment="Top" Width="366">
<TabControl.Resources>
<Style TargetType="TabItem" x:Key="tab1ItemHeaderStyle">
<Setter Property="HeaderTemplate" >
<Setter.Value>
<DataTemplate DataType="{x:Type TabItem}">
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Path=Header, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TabItem}}"/>
<Label Content="{Binding Path=UC1Figure, ElementName=uc1}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Style="{StaticResource tab1ItemHeaderStyle}" Header="[Tab 1]" Name="tabItem1" Width="100">
<vw:UserControl1 x:Name="uc1"></vw:UserControl1>
</TabItem>
<TabControl>
</Grid>
UserControl1.xaml
<Grid>
<Label Height="43" HorizontalAlignment="Left" Margin="69,128,0,0" Name="textBlock1" Content="{Binding Path=UC1Figure, ElementName=uc}" VerticalAlignment="Top" Width="100" />
<Button Name="updateSomeFigure" Content="Press Me" Click="updateSomeFigure_Click" Width="100" Height="100" Margin="69,12,66,71" />
</Grid>
UserControl1.xaml.cs
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public static readonly DependencyProperty SomeFigureProperty =
DependencyProperty.Register("UC1Figure", typeof(int), typeof(UserControl1));
public int UC1Figure
{
get { return (int)this.GetValue(SomeFigureProperty); }
set { this.SetValue(SomeFigureProperty, value); }
}
private void updateSomeFigure_Click(object sender, RoutedEventArgs e)
{
UC1Figure = UC1Figure + 1;
}
}
If you want to data bind a property to the UI of your UserControl, you have two options. The first is to implement the INotifyPropertyChanged Interface in your code behind. The second is to define DependencyPropertys instead of regular CLR properties. You can find out how to do that in the Dependency Properties Overview page on MSDN.
You might also want to read the Data Binding Overviewā€ˇ page on MSDN before you start data Binding.

Content control binding not working

When i set the content of the content control like below but the binding of the element inside the content get break.
i have given a content inside a property of a class and set the property as the content to the content control.
[Xmal]
<Grid>
<Button HorizontalAlignment="Center"
VerticalAlignment="Top"
Click="Button_Click_1"
Content="Click" />
<local:MyTile x:Name="mytile">
<local:MyTile.TileViewContent>
<StackPanel>
<TextBox x:Name="text"
Background="Red"
Text="MyText" />
<TextBox Text="{Binding ElementName=text, Path=Text,Mode=TwoWay}" />
</StackPanel>
</local:MyTile.TileViewContent>
</local:MyTile>
<ContentControl x:Name="contentcontrol" />
</Grid>
[C#]
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
contentcontrol.Content = mytile.TileViewContent;
}
}
public class MyTile:Control
{
public FrameworkElement TileViewContent
{
get { return (FrameworkElement)GetValue(TileViewContentProperty); }
set { SetValue(TileViewContentProperty, value); }
}
public static readonly DependencyProperty TileViewContentProperty =
DependencyProperty.RegisterAttached("TileViewContent", typeof(FrameworkElement), typeof(MyTile), new PropertyMetadata(null));
}
When i set the content the binding not working. please help
If you want to simply binding is works, not necessarily through ContentControl, use the Style for your element:
<Window.Resources>
<Style x:Key="MyTemplateForMyControl" TargetType="{x:Type local:MyTile}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyTile}">
<StackPanel>
<TextBox x:Name="MyTextBox" Text="MyText" Background="Red" />
<TextBox Text="{Binding ElementName=MyTextBox, Path=Text}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Click" Click="Button_Click_1" />
<local:MyTile x:Name="MyTile" />
</Grid>
In code we are set the Style for your Control:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
MyTile.Style = this.Resources["MyTemplateForMyControl"] as Style;
}
If it is necessary to use ContentControl I can recommend instead of you Control use a DataTemplate:
<Window.Resources>
<DataTemplate DataType="{x:Type local:MyDataForTemplate}">
<StackPanel>
<TextBox x:Name="MyTextBox" Text="{Binding TextBoxContent}" Background="Red" />
<TextBox Text="{Binding ElementName=MyTextBox, Path=Text}" />
</StackPanel>
</DataTemplate>
<!-- Some data -->
<local:MyDataForTemplate x:Key="MyDataForTile" TextBoxContent="MyText" />
</Window.Resources>
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Content="Click" Click="Button_Click_1" />
<ContentControl Name="TileContentControl" />
</Grid>
There will be some data for a template:
public class MyDataForTemplate
{
string textBoxContent = "";
/// <summary>
/// Text for TextBox
/// </summary>
public string TextBoxContent
{
get
{
return textBoxContent;
}
set
{
textBoxContent = value;
}
}
}
In code we are set the data for a template:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
TileContentControl.Content = this.Resources["MyDataForTile"] as MyDataForTemplate;
}

Resources