Wpf: Apply custom style of ToolTip at multiple controls - c#

I am working with WPF application. I have created a custom control library where I have customized all controls, meaning added some functionality and restyled them. Same way I have restyled the ToolTip as well. I am using this custom library in other projects. Everything is working fine except ToolTip. ToolTip style is not getting applied. Any Help plz.
Edit:
I have created a custom class named ToolTip that derives from System.Windows.Controls.ToolTip, I have declared style for my custom class as well. Now I want to know how can I get this style applied for ToolTip of each control, I mean I want to create object of my ToolTip whenever user set ToolTip on a control.
in .cs:
public class ToolTip : System.Windows.Controls.ToolTip
{
static ToolTip()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ToolTip), new FrameworkPropertyMetadata(typeof(ToolTip)));
}
}
in .xaml(Resource Dictionary):
<Style TargetType="{x:Type local:ToolTip}">
<Setter Property="VerticalOffset" Value="-2" />
<Setter Property="HorizontalOffset" Value="20" />
<Setter Property="Height" Value="35"></Setter>
<Setter Property="Placement" Value="Top" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ToolTip}">
<Grid Name="Border" Background="Transparent" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<Rectangle RadiusX="7.5" RadiusY="7.5">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0.5,-0.5" EndPoint="0.547,0.913">
<GradientStop Color="#FFEEEEEE" Offset="0"/>
<GradientStop Color="#FFBBBBBB" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter Margin="10,0,10,0" HorizontalAlignment="Center" VerticalAlignment="Center" TextBlock.Foreground="Black" TextBlock.FontSize="12" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any Help plz.

Placing the default ToolTip Style in a shared ResourceDictionary in a separate assembly will allow it to be used by multiple projects. You can merge in the MyDefaultStyles ResourceDictionary in the Resources folder of the SharedStyleLibrary.dll into App.xaml using:
<App.Resources>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/SharedStyleLibrary;component/Resources/MyDefaultStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</App.Resources>
If MyDefaultStyles contains an implicit ToolTip Style (<Style TargetType="{x:Type ToolTip}">
) it will be used as the default. You can also target it more locally by instead giving the Style an x:Key and then creating an implicit ToolTip Style in whatever scope you want it to apply (i.e. Window, UserControl, single layout Panel):
<Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource ExternalLibraryNamedStyle}">...

If your custom ToolTip class is only for the sake of applying templates, it's much easier to use an Implicit Style for your ToolTips:
<Style TargetType="{x:Type ToolTip}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<!-- rest of your style here -->
</Style>

Related

WPF Grouping formattings within a single style

I am working on a WPF application where I by now have a lot of different Resource Dictionaries comprising a huge amount of styles. Many of those styles describe brush settings for borders, backgrounds, etc. Until now, every formatting is in a separate style.
However, what I would like to do (if possible) is to "group" different styles that belong together into a "parent" style - thereby being able to make it a little more manageable which styles concerns which controls.
For example, for a GroupBox, the settings would ideally be registered in a style like this:
<Style x:Key="GroupBoxFormat">
<Style.Resources>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1" x:Key="ElementGradientBrush">
<GradientStop Color="AntiqueWhite" Offset="0" />
<GradientStop Color="Tan" Offset=".7" />
</LinearGradientBrush>
<Border x:Key="BorderFormat" BorderThickness="2">
<Border.Background>
<SolidColorBrush Color="Gold"></SolidColorBrush>
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="Black" ></SolidColorBrush>
</Border.BorderBrush>
</Border>
<FontFamily x:Key="TitleFontFamily">
Arial
</FontFamily>
<FontWeight x:Key="TitleFontWeight">
Bold
</FontWeight>
<!-- Other formats go here... -->
</Style.Resources>
</Style>
As seen in the listing, all separate resources within the style have x:Key attributes specified. As this is seemingly required (as VS complains if it is missing), there must obviously be a reason for that.
From elsewhere in the XAML code, the style can be referenced with {StaticResource GroupBoxFormat}. However, if I want to refer from outside to any of the "inner" properties, say, "BorderFormat" - how do I do that? Something like "dot" notation within C# for accessing object members like SomeObject.SomeMember. Staying in the example, It could be illustrated like "GroupBoxFormat.BorderFormat". I just need the "XAML" way of doing that.
There is nothing like what you're asking for with the "dot notation within C#". The only thing I can suggest is to define global styles in your App.xaml without defining a Key but defining a TargetType:
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="3"/>
<Setter Property="MinWidth" Value="110"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
Now all of your TextBox controls will have these properties defined. If you'd like a specific TextBox to have a different style you must define another TextBox style but set the x:Key attribute as well as the TargetType and then reference the Key.
<TextBox Style{StaticResource YourKey}/>

round combo box border

friends
i find this code to make round combo box but i don't know how to use
is there any one can help how to use this code
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border CornerRadius="5">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
what should i do to apply this code to my combo box in wpf
This template you are showing here is just a basic idea, but not something really working. You need to override the full default template and customize it for your needs. Inside of your UserControl’s resources ass a template (just copy and paste) from this link default combobox template
<UserControl.Resources>
<!-- paste the code here-->
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
….
<ControlTemplate x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
….
</UserControl.Resources>
Then modify the border radius in two places:
…
Grid.ColumnSpan="2"
CornerRadius="<put a new radius here, for example 20>"
BorderThickness="1">
…
And here
<Border Grid.Column="0"
CornerRadius="<new value, for example 20>,0,0,<new value, for example 20>"
Margin="1" >
This should do it. Since you did not specify the key name for the template the combobox should pick a new template up automatically.

how can I design a radio button as a main design and change the main design per button

I have five radio buttons all of them have common style but different color. The styles are all separated. I would like to do a main style and to be able to change the background color for each of them separately.
Define the template in a common base style (e.g. RadioButtonBaseStyle), where you don't hard-code the background color, but use {TemplateBinding Background} instead ; then create several styles based on RadioButtonBaseStyle where you just change the Background property with a setter.
Example:
<Style x:Key="RadioButtonBaseStyle" TargetType="RadioButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RadioButton>
...
<Ellipse Fill="{TemplateBinding Background}" />
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlueRadioButtonStyle" TargetType="RadioButton" BasedOn="{StaticResource RadioButtonBaseStyle}">
<Setter Property="Background" Value="Blue" />
</Style>
If you need finer control, you could create additional attached properties and use them instead of the standard Background/Foreground/BorderBrush, as explained in this blog post: http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/

How to use xaml vector images as image source in Windows 8 app

I created some assets in inkscape and would like to use them as icons in a windows 8 application. I have done some reading and it seams that while .Net 4.5 supports SVG, the modern ui profile does not. I converted the svg to xaml using this tool.
I get the following xaml.
<Canvas xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="svg2997" Width="744.09448" Height="1052.3622" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Canvas x:Name="layer1">
<Path Fill="#FFCCCCCC" Stroke="#FF000000" StrokeThickness="1.34377062" StrokeMiterLimit="4" x:Name="path3007" Data="M372.58272,134.72445C167.96301,134.72445 2.06820310000001,300.58818 2.06820310000001,505.20789 2.06820310000001,709.8276 167.96301,875.72241 372.58272,875.72241 577.20243,875.72241 743.06616,709.8276 743.06616,505.20789 743.06616,300.58818 577.20243,134.72445 372.58272,134.72445z M280.73888,251.77484L455.94149,251.77484 455.94149,413.70594 628.16035,413.70594 628.16035,588.97071 455.94149,588.97071 455.94149,773.71514 280.73888,773.71514 280.73888,588.97071 106.22005,588.97071 106.22005,413.70594 280.73888,413.70594 280.73888,251.77484z" />
</Canvas>
</Canvas>
If I add this directly to my apps xaml it will render however the scale is way off.
I would like to use this as an image source for an image object if possible.
<Image HorizontalAlignment="Left" Height="100" Margin="127,37,0,0" VerticalAlignment="Top" Width="100" Source="Assets/plus_circle.xaml"/>
Can this be done?
Most AppBar buttons are based on a style included in StandardStyles called AppBarButtonStyle.
To customize the text of the button you set the AutomationProperties.Name attached property, to customize the icon in the button you set the Content property, and it's also a good idea to set the AutomationProperties.AutomationId attached property for accessibility reasons.
Here's an example of a button customized using this approach:
<Style x:Key="FolderButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="FolderAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Folder"/>
<Setter Property="Content" Value=""/>
</Style>
As mentioned above, to customize the icon you set the Content property. The challenge is how you set the content so it displays your custom vector art.
It turns out you can place any path Xaml, even yours, into a Viewbox to change its scale. That was my first approach, but it doesn't work. In fact, it seems any time you use Xaml expanded notation to set the Content property for a button it doesn't work.
<Style x:Key="SquareButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="SquareAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Square"/>
<Setter Property="Content">
<Setter.Value>
<!-- This square will never show -->
<Rectangle Fill="Blue" Width="20" Height="20" />
</Setter.Value>
</Setter>
I actually think this is a bug, but luckily there is a workaround.
Tim Heuer wrote an excellent article on the simplest way to use a Xaml Path as the artwork for a button. That article is here:
http://timheuer.com/blog/archive/2012/09/03/using-vectors-as-appbar-button-icons.aspx
In short, you need to define a style that sets up all the bindings correctly:
<Style x:Key="PathAppBarButtonStyle" BasedOn="{StaticResource AppBarButtonStyle}" TargetType="ButtonBase">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Path Width="20" Height="20"
Stretch="Uniform"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}"
Data="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DataTemplate>
</Setter.Value>
</Setter>
Then you create a style that inherits from that style and you paste in your path. Here is the style for your artwork you listed above:
<Style x:Key="CrossButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource PathAppBarButtonStyle}">
<Setter Property="AutomationProperties.AutomationId" Value="CrossAppBarButton"/>
<Setter Property="AutomationProperties.Name" Value="Cross"/>
<Setter Property="Content" Value="M372.58272,134.72445C167.96301,134.72445 2.06820310000001,300.58818 2.06820310000001,505.20789 2.06820310000001,709.8276 167.96301,875.72241 372.58272,875.72241 577.20243,875.72241 743.06616,709.8276 743.06616,505.20789 743.06616,300.58818 577.20243,134.72445 372.58272,134.72445z M280.73888,251.77484L455.94149,251.77484 455.94149,413.70594 628.16035,413.70594 628.16035,588.97071 455.94149,588.97071 455.94149,773.71514 280.73888,773.71514 280.73888,588.97071 106.22005,588.97071 106.22005,413.70594 280.73888,413.70594 280.73888,251.77484z"/>
</Style>
And finally, you use it in your AppBar like this:
<Button Style="{StaticResource CrossButtonStyle}" />
Dev support, design support and more awesome goodness on the way:
http://bit.ly/winappsupport
I'm pretty positive you can't just inject Path Data into an Image Source and expect it to magically work unless it's through a Drawing Object as Source. What you can however do is adopt your Path into a ContentControl for re-use in the same way without having to go through the trouble of Drawing objects for every instance.
So instead of;
<Image Source="..."/>
Just do something like this and plop it in your Object.Resources or ResourceDictionary;
<Style x:Key="YourThingy" TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Path Fill="#FFCCCCCC" Stroke="#FF000000" StrokeThickness="1.34377062" StrokeMiterLimit="4" x:Name="path3007" Data="M372.58272,134.72445C167.96301,134.72445 2.06820310000001,300.58818 2.06820310000001,505.20789 2.06820310000001,709.8276 167.96301,875.72241 372.58272,875.72241 577.20243,875.72241 743.06616,709.8276 743.06616,505.20789 743.06616,300.58818 577.20243,134.72445 372.58272,134.72445z M280.73888,251.77484L455.94149,251.77484 455.94149,413.70594 628.16035,413.70594 628.16035,588.97071 455.94149,588.97071 455.94149,773.71514 280.73888,773.71514 280.73888,588.97071 106.22005,588.97071 106.22005,413.70594 280.73888,413.70594 280.73888,251.77484z" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then just plop it on your view wherever and as many times as you like;
<ContentControl Style="{StaticResource YourThingy}"/>
You will however want to play with that Path of yours. It seems set a large size, but hopefully this provides a good alternative for your circumstance. Cheers!

DatePicker custom template leaves a white box inside

I am trying to make a custom template for datepickers in my program. I am basically using this template line for line (changing colors and things):
http://msdn.microsoft.com/en-us/library/cc278067(v=vs.95).aspx
I have tried going through it and getting rid of this white box (the one INSIDE the datepicker textbox), but it is evading me. Here is a screenshot of what I am seeing:
Do I have to add something extra? Or change some existing values? There is also a MouseOver event that highlights the whitebox with the blue windows gradient, if that helps..
For future people with this problem, I did what Brian suggested, just thought I would post exactly my code, so other people can use it ;) I just added this into app.xaml
<Style x:Key="{x:Type DatePickerTextBox}" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Border x:Name="watermark_decorator" BorderBrush="{DynamicResource cControlColor}" BorderThickness="1"
Background="{DynamicResource cControlColor}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT: Updating since the clarification points to the white rectangle around the 'Enter text here'.
For this, you need to create a custom template for the DatePickerTextBox which is defined about 2/3rds of the way down that template, and named TextBox. Your best bet will be to use Blend to create a custom template (since it will generate the default template) and then modify the <Border x:Name="watermark_decorator".../> to change the BorderBrush. For example:
<Style x:Key="MyDatePickerTextBoxStyle" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<!-- Visual State Manager stuff -->
<Border...>
<!-- other stuff... -->
<Border x:Name="watermark_decorator" BorderBrush="[THE BRUSH YOU WANT]" BorderThickness="1">
<!-- And so on and so forth... -->
</Border>
</Border>
</Grid>
</ControlTemplate>
</Setter>
</Style>
Then, in the DatePicker template, modify the DatePickerTextBox to use this style:
<!-- All DatePicker Template stuff -->
<controlsPrimitives:DatePickerTextBox x:Name="TextBox" Style="{DynamicResource MyDatePickerTextBoxStyle}" ... />
Are you talking about the button with the 15 on it? If so, the look and feel of this part of the DatePicker is defined in the "DropDownButtonTemplate" part of the template. This template includes a large VisualStateManager section, but then defines the template for that button. There are comments that define the beginning and end of the button template:
<!--Start UI-->
... this is the Button Template ...
<!-- End UI-->
For example, if you want to change the color of the Blue rectangle at the top of the button, the MSDN example uses this:
<Rectangle Grid.ColumnSpan="4" Grid.RowSpan="1" StrokeThickness="1">
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.48,-1" StartPoint="0.48,1.25">
<GradientStop Color="#FF494949" />
<GradientStop Color="#FF9F9F9F" Offset="1" />
</LinearGradientBrush>
</Rectangle.Stroke>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.3,-1.1" StartPoint="0.46,1.6">
<GradientStop Color="#FF4084BD" />
<GradientStop Color="#FFAFCFEA" Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
And you could change it to a solid color simply by changing it to this:
<Rectangle Grid.ColumnSpan="4" Grid.RowSpan="1" StrokeThickness="1" Stroke="Black" Fill="Green"/>
The "White Box" is actually the Border inside the template with the x:Name="BackgroundGradient", so if you change the Background of that element, you can get rid of the white.

Categories