Creating a custom control extending Image - wpf

I have a custom control extending Image, and I will put some more data on top of that image. However, when I am trying to style the component, I am getting the error that my Custom Control do not have the property Template Error:
Cannot find the Style Property 'Template' on the type 'MyCustomImage'
How can I style my custom control if Image does not have a Template Property?
Thanks
Edit:
Xaml:
<Style TargetType="{x:Type FieldComponents:MyCustomImage}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type FieldComponents:MyCustomImage}">
</ControlTemplate>
</Setter.Value>
</Setter>
</style>

Image inherits directly from FrameworkElement, not from Control, so it does not have a Template property. If you want to be able to template your control, you can inherit from Control or UserControl and have your template include an Image.

Related

Custom control not inheriting parent's styles

I'm trying to maintain a uniform look and feel across elements in my WPF application, and at the same time I want to create a modified TextBox. However, when I do this, styles that I define at the application level for TextBox aren't being applied to the class I created, even though the style created for my custom control is using the BasedOn property.
Is there something I'm missing that's causing this to behave differently than I expect?
I reproduced the issue in a brand-new WPF project in VS2010 with this setup:
C# Code:
public class CustomTextBox : TextBox
{
static CustomTextBox() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomTextBox), new FrameworkPropertyMetadata(typeof(CustomTextBox)));
}
}
XAML in Themes\Generic.xaml:
<Style TargetType="{x:Type local:CustomTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"/>
XAML in App.xaml:
<Application.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="Red"/>
</Style>
</Application.Resources>
However, in the designer and when I run the app, the CustomTextBox falls back onthe default styling for the text box instead of having a red background, even though the documentation for the BasedOn property suggests that my derived class should have this styling...
There are several ways that styles in WPF can be extended or inherited. Styles can be based on other styles through this property. When you use this property, the new style will inherit the values of the original style that are not explicitly redefined in the new style.
...
Note: If you create a style with a TargetType property and base it on another style that also defines a TargetType property, the target type of the derived style must be the same as or be derived from the type of the base style.
Short Answer: Your style is based on a StaticResource
<Style TargetType="{x:Type local:CustomTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"/>
When you did this, you are not changing the StaticResource
<Style TargetType="TextBox">
<Setter Property="Background" Value="Red"/>
</Style>
So CustomTextBox is not supposed to inherit the red background.

What is the most economical way to implement your own window border and title bar?

I am pretty new to WPF and am sitting here with my book trying to figure out the best approach to this application.
The title bar is not part of the client area so I am making my own title bar.
Which way would it be easiest to make this into some sort of resource to apply to all new windows I create?
<Application.Resources>
<Style x:Key="WindowTheme">
<Setter Property="Window.WindowStyle" Value="None"/>
</Style>
<!--Would I create a user control here for the title bar/border and title bar buttons? Or would it be a style?-->
</Application.Resources>
In WPF, there are two ways to use styles: Named styles and typed styles. A named style has an x:Key="..." attribute. A typed style doesn't have a name, but a TargetType="..." attribute (Rem: Named styles can and very often do have a TargetType as well, so named styles and unnamed styles would be more precise). Typed styles automatically get applied to all controls in the scope, which are of type TargetType (not a derived type).
<Style TargetType="{x:Type Window}">
<Setter Property="Background" Value="Blue" />
</Style>
To create your own window, you can set it's template property to a UserControl in the style:
<Style TargetType="{x:Type Window}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The professional way to implement the control template is to implement it 'from scratch', this means not using a UserControl which derives from Window. To do this, you define the visual tree of the Window, and use the WPF feature TemplateParts to define what part of your control template is responsible for what functionality of the window.
Here is a tutorial which describes pretty exactly what you want to do:
CodeProject tutorial

WPF: Set style on immediate children only

In my application I have a tab control which has several tab items.
The problem is that I want to apply a style to these tab items, but to no other (nested) tab items.
I have tried setting the following style on the tab control, but this also effects all children:
<Style x:Key="tabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="TabItem.Template" Value="{StaticResource tabItemTemplate}" />
</Style>
By using the code above I get the following error: 'TabItem' ControlTemplate TargetType does not match templated type 'TabControl', as TabItem and TabControl have the same DependencyProperty "Template", and the code tries to set the TabItemTemplate as TabControl- Template.
Can anybody help me?
Use the ItemContainerStyle property to apply a style to the items of an items control:
<Style x:Key="tabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="ItemContainerStyle" Value="{x:StaticResource tabItemStyle}" />
</Style>

WPF Custom Control TemplateBinding

How do i define a TemplateBinding for my custom control?
a little somthing like this..... (btw, this xaml is WPF, not silverlight--which is slightly different)
<style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background={TemplateBinding Background}
</ControlTemplate>
</Setter.Value>
</Setter>
</style>
now, once you apply this style to an object, whenever you set the background of that object, the template will use the Background property (this is a property on the button control) and will be defaulted to what you set in the style (in this case, green)
If you want to use a property that does not exsist on the object of your style, you have to derive your own control and add the property as either a DependencyProperty or use the INotifyPropertyChanged interface. Here is a decent explanation for you.
Need a bit more information on what you are trying to do. Setting up a TemplateBinding can be done with the following XAML:
{TemplateBinding YourProperty}
or
{Binding RelativeSource={RelativeSource TemplatedParent}, Path=YourProperty}

Accessing an element defined in a style's template in wpf?

I have a wpf TabControl which I added a ScrollViewer to. This is all wrapped into a style which is situated in a resource dictionary.
Now, on the window's xaml side, all I do is set
.
I would like to access the control viewer element, as defined in the style as follows:
<Style x:Key="MyTabStyle" TargetType="{x:Type TabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<ScrollViewer />
.......
How do I access the ScrollViewer which is so deeply nested in the hierarchy?
Give it a name (theScrollViewer for instance), and use the FindName method to access it :
ScrollViewer scrollViewer = theTabControl.Template.FindName("theScrollViewer") as ScrollViewer;

Resources