Xaml Grid Styling - wpf

New to WPF, I'm having some trouble creating a styles in my code, I was able to make some buttons styles by drawing rectangles and making them into buttons, this opened a template editor so I was able to do it.
Now I'm wanting to create a template for a repeating stackpanel/grid layout, and I wrote it by hand this time, but I am getting an error that says the "template is not a valid member"
This is the kind of thing I was trying to create, but the Property="Template" bit is underlined in red. Can somebody explain to me the reason behind this? How do I create or initialize the template?
<Style x:Key="LaneStyle" TargetType="{x:Type Grid}">
<Setter Property="Width" Value="760"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Grid}">
<!-- Things here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
If someone could direct me to a tutorial on styles/templates that would be nice as well, haven't been able to find one that explained it in more detail.

Grid is not a control, therefore you cannot apply a ControlTemplate to it. If you're looking for a "repeater" kind of thing, you should be using an ItemsControl.

The best way to create templates/styles is by using Microsoft Blend 3.0/4.0
Over there one can easily find out what's the progress after doing each change.
In your case, a grid cannot be styled as it is a container not a control. If you wish to customize some control need to modify the control template of the control.

Related

WPF styling deep nested elements

I can't override a default style attribute of a third-party component that I use in a clean way. The visual tree looks something like this:
A
--B
...
------------Z
--------------TextBlock
I try to override the style of TextBlock like this:
<Style
TargetType="A">
<Style.Resources>
<Style
TargetType="TextBlock">
<Setter
Property="TextWrapping"
Value="Wrap" />
</Style>
</Style.Resources>
</Style>
But this doesn't work. In live visual tree, I confirm that component A sees my custom style but TextBlock doesn't see it. However, when I try:
<Style
TargetType="Z">
<Style.Resources>
<Style
TargetType="TextBlock">
<Setter
Property="TextWrapping"
Value="Wrap" />
</Style>
</Style.Resources>
</Style>
It works though. Therefore, it seems to me that WPF forces me to add all of the child components one by one as Style.Resources to be able to edit the innermost child. But I don't want to define all of the resources between component A to Z just to add one simple style. What are my options?
I'm not sure if I fully understand your question, as you've provided a working answer, and I can't see why would WPF force you to 'define all of the resources between component A to Z'.
However, here is a tip:
You can create a custom control that inherits Z and overrides OnApplyTemplate(). When OnApplyTemplate() is called you're guaranteed that the template was applied, so you can find any child control (your textbox) you want. (Just google for e.g 'wpf find child control by name' if you don't know how.) Once you have your textbox, you can change its' wrapping from code.
I had to customize a Ribbon control once, and that approach greatly simplified the task.

Setting ALL colors on WPF ComboBox using styles?

I asked this question a few days ago and got some answers, non of which really helped me with the problem, so I am trying a fresh approach.
I want to be able to set the colors (foreground, background, and border) of the textbox used by a comboBox so that it can have a number of different values, based on a trigger. With a textbox, this is easy, just use setters on those properties and you are done.
So given that I have a trigger as follows:
<Trigger Property="someProperty" Value="true">
<!-- Insert Setters Here -->
<Setter Property="Foreground"
Value="Red" />
</Trigger>
What Setters would I insert into the above to change the 3 aforementioned colors of the textbox used by the combobox? For each trigger, assume that every color will change. It appears that Foreground works except for disabled.
I am under the impression that changing the colors based on an "IsEnabled" trigger (when false) can be tricky, but not sure why. But I need to support that and a number of other triggers based on custom attached properties or validations.
For the background, I have tried a whole bunch of options including ComboBox.Background, TextElement.Background, Panel.Background, etc., but all I get is a plain white background.
One other thing occurred to me is that if those should work, there may be some resource library in the calling tree that may be setting the background color in a way that won't allow me to change it, but, if so, how would I be able to find out?
Thank you!
As I told you in your last (now duplicated) question, you will need to define a new ControlTemplate to achieve your goal.
For future reference:
Asking duplicate questions on StackOverflow is not approved by the community, especially if you are asking a duplicate of your own question. If you do not understand your answer(s) or do not feel that they answer your question adequately, you should ask the answer author(s) to explain it further in that question.
Now I'll get off my soap box and get you further on your way to achieving your goal. As I said, you will need to define a new ControlTemplate... there is no way around this. The reason for this is simple - you want to add Triggers to affect the XAML controls that are defined inside the default ControlTemplate, but you have no other way to do this from XAML.
So, how do we define a new ControlTemplate? It's quite simple really: we just define some XAML in the Template property that describes the way that we want the control to look and behave. Please refer to the link that I provided you with for help with this in your last post. Additionally, here is a very simplified example:
<Style TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border Name="Border" CornerRadius="2" Padding="2">
<ScrollViewer Margin="0" HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Apply this Style to a ComboBox with the IsEnabled property set to False and you will see that it is red. Now you're probably thinking 'that doesn't look like a ComboBox' and you'd be right. That's because I just replaced all of the XAML from the default ComboBox ControlTemplate with a little bit that slightly resembles just the drop down section for simplicity.
Your job now is to define your own ControlTemplate that replicates the default XAML and adds the relevant Triggers that I have shown you in this and your last post. In the example, notice how the Trigger.TargetName is set to Border, which is the name of the internal Border control used. You will need to do this for each element that you want to colour.
Here is a link to the default ControlTemplate for the ComboBox control. When you see how large it is, you will understand why I didn't use it in the example.
ComboBox Styles and Templates

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 comboBox Arrow Button

I'm doing a wpf project and inside my application i have a combobox.Can i know any simple way to change the dropDown arrow color? I found the resource here, but its too complicate. Anyone can help me out?
p/s: i'm a newbie
combobox example:
Because the arrow is just linked to a system resource, I believe there's no way to change it other than redoing the entire template like you see in your linked article. It seems complicated, but it's not so bad, especially if you have Blend (just because Blend makes it easy to pull out the current template to edit it).
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Path x:Name="Arrow" Fill="White"/>
</ControlTemplate>
</Setter.Value>
</Setter>

silverlight 3.0 grid row selector color

is it possible to specify the color for the row selector in silverlight grid
Yes but you need to copy the control template for the DataGridRowHeader control and place it in a Style object in a resource:-
<UserControl.Resources>
<Style x:Key="CustomRowHeader" TargetType="DataGridRowHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="localprimitives:DataGridRowHeader">
<!-- Copy of the rest of the standard controls template -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<UserControl.Resources>
<DataGrid RowHeaderStyle="{StaticResouce CustomRowHeader}" ... >
Now you can fiddle around with the color value and pretty much anything else that is used to render the row selector.
You can probably do this with Blend fairly well if you have it and are familiar with using it. I prefer to copy the template from the documentation. See DataGrid Styles and Templates
No, but it's perfectly possible to subdivide a grid into rows/columns and fill them with rectangles+background or something like that.

Resources