How can I set the style of a Button? I use Xceed.wpf.toolkit
Xceed.Wpf.Toolkit.MessageBox mbox = new Xceed.Wpf.Toolkit.MessageBox();
System.Windows.Style style = new System.Windows.Style(typeof(System.Windows.Controls.Button));
style.Setters.Add( new System.Windows.Setter(System.Windows.Controls.Button.ForegroundProperty, Brushes.DarkGreen));
mbox.OkButtonStyle = style;
I get the error
System.Windows.Markup.XamlParseException: ''System.Drawing.SolidBrush' is not a valid value for the 'System.Windows.Documents.TextElement.Foreground' property on a Setter.'
Be sure to use the WPF libraries and not the WindowsForms or GDI+ ones...
What you should use: System.Windows.Media.Brushes which contains DarkGreen as System.Windows.Media.SolidColorBrush (in PresentationCore.dll).
What you currently use is System.Drawing.Brushes and System.Drawing.SolidBrush.
TextElement.Foreground is of type System.Windows.Media.Brush. That's it's "data type". You have to assign it a value of that type, or some subclass of that type.
System.Drawing.Brushes.DarkGreen is of type System.Drawing.Brush, which is not a subclass of System.Windows.Media.Brushes. That's from Windows Forms or something, not WPF. You need to use a WPF brush object for a WPF control.
Get rid of using System.Drawing; at the top of your C# file. In a WPF project, that'll cause you nothing but trouble. Use System.Windows.Media.Brushes.DarkGreen instead.
style.Setters.Add( new System.Windows.Setter(System.Windows.Controls.Button.ForegroundProperty,
System.Windows.Media.Brushes.DarkGreen));
You could also create the Style as a XAML resource and load it with FindResource(). Then you'd just say "DarkGreen" and let the XAML parser worry about what kind of brush to create:
<Style
x:Key="XCeedMBoxButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Type Button}}"
>
<Setter Property="TextElement.Foreground" Value="DarkGreen" />
</Style>
C#
var style = FindResource("XCeedMBoxButtonStyle") as Style;
But then you've got to worry about defining it someplace where it can be found, and what you're doing will work OK anyhow if you just use the right Brush class.
It's pretty gruesome that we've got multiple classes called Brush in multiple .NET namespaces with uninformative names like "System.Windows.Media" vs "System.Drawing", but unfortunately it all just sort of grew that way.
Related
Is it possible to subclass a control (AppBarToggleButton in my case) and "inherit" TargetType of the base class? What I want to achieve is to have a slightly customized AppBarToggleButton (with disabled auto-toggle behavior) put into CommandBar and make it look exactly as if it was regular AppBarToggleButton (i.e. receive style whatever is defined for AppBarToggleButton inside given command bar control template). They say, DefaultStyleKey should help, but it is inherited fine, but, alas, doesn't seem to participate in local style resolution/lookup.
I may need to subclass other controls for various purposes, so the ultimate goal here is to understand how local style resolution works internally and does target instance has any involvement in it or is it a completely external process.
In general, we need make Templated Control for custom AppBarToggleButton. When we make Templated Control with Visual Studio, it will generate Generic.xaml file in the Themes folder that used to declare the custom control's style. And the the custom control cs file like the following.
public sealed class CustomAppBarToggleButton : AppBarToggleButton
{
public CustomAppBarToggleButton()
{
this.DefaultStyleKey = typeof(CustomAppBarToggleButton);
}
}
If you don't want to edit the default style you could remove DefaultStyleKey line that used to binding current control with the style in the Generic.xaml file.
Open Generic.xaml file you will find the following. And it's empty style. If we want to do some small changes, you need copy the complete AppBarToggleButton style to replace it and edit the TargetType to local:CustomAppBarToggleButton. Then you can edit the style base on your requirement.
<Style TargetType="local:CustomAppBarToggleButton" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CustomAppBarToggleButton">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And if your want to make a new dependency property, please define it in the cs file then use TemplateBinding to bind the property in the style. For more please check this document.
For anyone still stumbling upon this. I managed to solve a similar issue, inheriting from Button, using the approach described here https://stackoverflow.com/a/71338869/10468107
Specifically, adding
<Style BasedOn="{StaticResource DefaultButtonStyle}" TargetType="local:MyButton" />
solved it for me. So maybe it works for other types as well, using {StaticResource Default<TYPE>Style}
I have a similar need and am wondering if the answer is still the same. I have extended the basic ComboBox control to meet some behavioral requirements.
class ExtendedComboBox : ComboBox
I want the ExtendedComboBox instances to inherit the latest platform styling but they are instead getting styled differently. The first of these is an ExtendedComboBox (square corners, larger glyph), while the second is a generic ComboBox (rounded corners, smaller glyph).
The requirement is to have the two combo boxes styled the same way. I am reluctant to create an explicit Style for ExtendedComboBox because then if the style for the generic ComboBox changes the ExtendedComboBox will no longer match. Is there some way to just inherit the standard style?
I have an application, which uses WPF on windows as toolkit framework. Now I would like to set the width of scrollbars for my ScrollViewers programmatically. I found many examples to set the width via XAML. But how can I define the width of scrollbars programmatically?
Unfortunately I could not find any property or method on ScrollViewer to set the width of scrollbars.
var viewer = new ScrollViewer();
viewer.MagicProperty = 42; // Does not exist
Also all properties on SystemParameters are unfortunately read-only.
VerticalScrollBarWidth.VerticalScrollBarWidth = 42; // Read-only
Edit: WPF is only one of multiple toolkit frameworks in my application. I use a custom GUI abstraction layer for supporting Windows (WPF), Linux (GTK#) and MacOS X (in future). My user interface is encapsulated in an OS independent way. Therefore it makes no sense to use XAML.
Easiest way is to set x:Name property, then you can access ScrollViewer in your code.
Or use Binding: http://www.tutorialspoint.com/wpf/wpf_data_binding.htm
Binding will be useful if you want to manipulate with multile ScrollViewers and set same values.
EDIT:
You can create ScrollViewer in your code and then set its parameters. But you need a way to insert it into VisualTree among other controls. So you need to get instance of some container and then use its Children.Add() method
However I'd really recommend to use as much XAML as you can and leave your code for application logic, not the UI building.
EDIT 2:
Can you try:
Style myStyle = new Style(typeof(ScrollBar));
myStyle.Setters.Add(new Setter(WidthProperty, 40));
scrollViewer.Style = myStyle;
EDIT 3:
I found a solution. You can add ResourceDictionary.xaml and add this style to it:
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="MinWidth" Value="35" />
<Setter Property="Width" Value="35" />
</Style>
Then load it at runtime like so:
Resources.MergedDictionaries.Add(Application.LoadComponent(new Uri(#"Dictionary.xaml", UriKind.Relative)) as
ResourceDictionary);
I'm creating a new style for the TabControl including a new ItemContainerStyle for the items. The new style works fine, except that I need the possibility to add features to the ItemContainerStyle when using the style. In detail this is the Header property
<TabControl x:Name="myTabControl" SelectionChanged="myTabControl_SelectionChanged">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}"></Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
which works OK. But it overrides the style completely. the BasedOn property would help, but I don't have access to the key of the ItemContainerStyle since it is embedded in the TabControls' style. How can I simply update a property of the style without overriding the style completely?
Thanks
There is a bit of a difference in the way styles in WPF compared to css. In Wpf they work completely off of inheritance, this is the basic document on how styles work. So if a key is not provided for you I think you are out of luck when using the BasedOn inheritance.
However, Microsoft does provide a useful utility in Visual Studio Blend. In the Objects and Timelines Window you right click then select an "edit a style", This will do all the heavy lifting for you. If you are going to be doing a lot of small changes on the style I would suggest you make a copy, and give it a Key, then use the BasedOn property to make your small changes that you want.
I Hope this helps.
You can base your style on the implicitly applied default style:
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
I am trying to setup a windows.resoruces style that targets all textbox's within all groupbox's (so it would not target textbox's that are not found within a groupbox)
I know I could use the x:key field, but was wondering if there was a way to target certain controls within controls for an entire window or application?
You could try a nested style for your TextBoxes in Style.Resources of GroupBox with Style.TargetType but without x:key.
<Style TargetType="GroupBox">
<Style.Resources>
<Style TargetType="TextBox">
...
</Style>
</Style.Resources>
</Style>
One trick you could use is to define Textbox style without the x:key field. This one will apply to all the TextBoxes that do not have a Style specified.
Use this Style for the TextBoxes within the GroupBoxes by not using the Style Tag on these Boxes and for all other TextBoxes use a specific named Style by using the Style tag...
Help me Convert this WPF to Silverlight
I am interested in a Charles Petzold C# example that shows how to do a fisheye effect ( http://www.charlespetzold.com/blog/2009/05/Realizing-a-Fisheye-Effect-in-Silverlight.html ). The XAML code samples are in WPF but I want to try this in Silverlight.
When I try to create the XAML code in Silverlight, the compiler complains in two locations:
<Style TargetType="{x:Type Button}">
Error 1 The type 'x:Type' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.
<Style.Triggers>
Error 2 The attachable property 'Triggers' was not found in type 'Style'.
How do I convert this to Silverlight?
Do not use x:Type in Silverlight, doesn't support that markup extension. Just use <Style TargetType="Button">. As far as triggers, you can use them directly in the control xaml, not in style.
<Button>
<Button.Triggers>
</Button.Triggers>
</Button>
In the first case, with Button being in scope, you would do,
<Style TargetType="Button">
But in the second case, Triggers isn't (fully) supported by Silverlight, so you would likely need to implement anything that happens there within the appropriate event handlers (in code).