I have a User Control that works in the sense that it displays the data that it needs to display, the issue I have is the the style doesn't appear to be working in the most inner ItemsControl.
The style is working on the outer ItemsControl, which kind of has me stumped.
App.Xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionaries/StyleDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
UserControl.xaml
<ItemsControl ItemsSource="{x:Bind Cat.Content}">
<ItemsControl.ItemTemplate>
<DataTemplate >
<StackPanel>
<TextBlock Text="{Binding Header}" Style="{StaticResource myStyleTextBlock_Header}" />
<ItemsControl ItemsSource="{Binding Body}">
<DataTemplate>
<StackPanel>
<TextBlock Style="{StaticResource myStyleTextBlock_Paragraph}" Text="{Binding Body}"/>
</StackPanel>
</DataTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I was reading something about styles being encapsulated within User Controls, but if the outer style in the template works why does the second one not get applied.
Edit:
Maybe I should try to explain what I am trying to do and someone can suggest a better way.
Right now I have a class that has something like this.
public class Content
{
public string Header { get; set; }
public List<string> Body { get; set; }
}
And the user control is them just
<UIControls:DisplayDossierText />
The style is very simple, it is just styling a textbox to have colors and margins etc.
<Style TargetType="TextBlock" x:Key="myStyleTextBlock_PageHeader">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontSize" Value="30" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Margin" Value="0,0,25,15" />
<Setter Property="Foreground" Value="#007bb8" />
</Style>
<Style TargetType="TextBlock" x:Key="myStyleTextBlock_Paragraph" BasedOn="{StaticResource myStyleTextBlock_Header}">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="Margin" Value="0,5,15,30" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="#ff00063e" />
</Style>
So the idea is that the control displays the header, the the collection of body in the style. As state above, the header is styled fine, but the body text has no style applied to it at all.
I have been trying to find a good solution to this, best way to approach it and found nothing. So playing around I cam up with what I have at the moment, but I feel that this is probably not the best solution to what I am trying to achieve.
There is currently no Code Back for this, but the normal shell of code created when creating the control.
Anyway, I am getting the suspicion that I need to be going in a different direction and not really sure how to go about this. All examples I find are based on styling a control with the basics of a button or listview. While listview is kind of what this is, it will not be interactive. It's main purpose is to provide an easy way to change paragraphs of text and store it in a database and then pull it up and display it.
Anyone?
Related
I'm currently looking at the UWP CommunityToolkit DataGrid. I've been through the docs, but I'm not finding them clear on how to apply a ColumnHeaderStyle. I'm not sure what I should be targeting in the column header to set my style. I'm wishing to change the background and foreground colors. I would also like these properties to apply across the whole header, not just individual columns.
<controls:DataGrid.ColumnHeaderStyle>
<Style TargetType="">
<Setter Property="" Value=""/>
</Style>
</controls:DataGrid.ColumnHeaderStyle>
This one had me puzzled for a while, but I eventually discovered you need to add another XML namespace declaration in order to target the column header.
<Application
x:Class="MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:controlsprimitives="using:Microsoft.Toolkit.Uwp.UI.Controls.Primitives">
So in this case I just appended:
xmlns:controlsprimitives="using:Microsoft.Toolkit.Uwp.UI.Controls.Primitives"
Then you can create a style with this target:
<Style x:Key="ColumnHeaderStyle" TargetType="controlsprimitives:DataGridColumnHeader">
<!-- style properties -->
</Style>
(As of writing this, however, there seems to be weird styling behavior in doing this for some reason.)
You can override DataGridColumnHeaderBackgroundBrush and DataGridColumnHeaderForegroundBrush in your App.xaml as below:
<SolidColorBrush x:Key="DataGridColumnHeaderBackgroundBrush" Color="#FFCB2128" />
<SolidColorBrush x:Key="DataGridColumnHeaderForegroundBrush" Color="#FFB03060" />
The answer from #user1559112 got me on the right track, but it took some time to realize that in order to deal with the "weird styling behavior", it wasn't enough to just add a setter for the Background. I had to override the template like this:
<controls:DataGrid.ColumnHeaderStyle>
<Style TargetType="controlsprimitives:DataGridColumnHeader">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="prms:DataGridColumnHeader">
<ContentPresenter Background="{ThemeResource HeaderBackgroundBrush}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</controls:DataGrid.ColumnHeaderStyle>
When I added style to AutoSuggestBox Query Icon disappears. Any solutions?
<Page.Resources>
<Style x:Key="AutoSuggestBoxStyle" TargetType="AutoSuggestBox">
<Setter Property="TextBoxStyle">
<Setter.Value>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="20"/>
</Style>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Page Resources Style
<AutoSuggestBox
x:Name="autoSuggestBox"
Height="40"
Margin="24,44,24,0"
Text=""
PlaceholderText="Wyszukaj serial..."
QuerySubmitted="autoSuggestBox_QuerySubmitted"
SuggestionChosen="autoSuggestBox_SuggestionChosen"
TextChanged="autoSuggestBox_TextChanged"
QueryIcon="Find"
Style="{StaticResource AutoSuggestBoxStyle}"/>
XML AutoSuggestBox
Here is a better way.
You can define another TextBox style which is based on the existing style AutoSuggestBoxTextBoxStyle.
So you simply put the following into your resource dictionary.
<Style x:Key="BigAutoSuggestBoxTextBoxStyle"
TargetType="TextBox"
BasedOn="{StaticResource AutoSuggestBoxTextBoxStyle}">
<Setter Property="FontSize" Value="20" />
</Style>
Then, just reference it on your AutoSuggestBox.
<AutoSuggestBox QueryIcon="Find"
TextBoxStyle="{StaticResource BigAutoSuggestBoxTextBoxStyle}" />
Ok, I have a solution:
1) First I edited template copy, after PPM in design mode on AutoSuggestBox
2) Then I set FontSize in Resources.
After a couple of hours searching the web, I turn to you all:
My WPF class library (.NET 3.5, COM visible) has a form in it, which uses an UserControl and a theme file.
The problem:
When using WPF Applications, the buttons work just fine, but in this .NET 3.5, COM Visible, class library, they won't show at all. Other objects from the library can be used and work.
What could be the problem? I'm leaning towards the resource dictionary that can't be found, or some of the resources that cannot be found, but I can't put my finger on it.
Any help would be most welcome!
Some code
The resources are set via the
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyLibrary;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
There we place - for now - a simple:
<Grid>
<lib:ImageButton ImageSource="/MyLibrary;component/Images/some_image.png" />
</Grid>
Not forgetting the reference for the library in the project and the xamls:
xmlns:lib="clr-namespace:MyLibrary;assembly=MyLibrary"
The MyLibrary holds this ImageButton - a simple button extension mainly to hold an image.
The WPF looks somewhat like:
<UserControl x:Class="MyLibrary.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib="clr-namespace:MyLibrary"
x:Name="me"
Width="auto"
Height="22"
HorizontalAlignment="Center" VerticalAlignment="Center">
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type library:ImageButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="False">
<Setter Property="Width" Value="22" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="True">
<Setter Property="Width" Value="auto" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Button x:Name="_button" Click="Button_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="auto">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ElementName=me, Path=ImageSource}" Stretch="Uniform" />
<TextBlock x:Name="_Text" Text="{Binding ElementName=me, Path=Text}" VerticalAlignment="Center" Margin="2, 0, 0, 0">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Resources>
</TextBlock>
</StackPanel>
</Button>
</UserControl>
The .cs side is fairly arbitrary I guess.
Finally, we have Generic.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyLibrary;component/Themes/MyTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Where "MyTheme" holds lots of templates, colours etc..
The problem most likely stems from the fact that your Class Library project has no idea that there are resource dictionaries you want to consume everywhere even though you merged your resource dictionaries in some file. The reason for this is that Visual Studio and Blend both look for an ApplicationDefinition file for global resource dictionaries to consume.
Class Library projects cannot have ApplicationDefinition files. However, there is a way you can share resources for design time viewing of your custom control project. A question on that topic and the answer can be found here (disclaimer: the link currently points to my answer).
Please take note that if you use the solution linked to above, you will still have to reference your resource dictionaries at the App.xaml level of any Application project that consumes your class library as your class library will not contain the specific styling..
Well this question is rather old but here goes:
After doing a lot of comparison i verified that the way to get it working is setting the following lines somewhere in your class library on the assembly level:
[assembly: ThemeInfo(
ResourceDictionaryLocation.None,
ResourceDictionaryLocation.SourceAssembly
)]
I have the following XAML (simplified):
<Window ...
<Window.Resources>
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="FontSize" Value="28" />
<Setter Property="Margin" Value="3" />
<Setter Property="Foreground" Value="Green" />
</Style>
</Window.Resources>
<StackPanel>
<ListBox ItemsSource=...
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Index}" />
<TextBlock Text="-" />
<TextBlock Text="{Binding Hours, StringFormat={}{0:00}}" />
<TextBlock Text=":" />
<TextBlock Text="{Binding Minutes, StringFormat={}{0:00}}" />
<TextBlock Text=":" />
<TextBlock Text="{Binding Seconds, StringFormat={}{0:00}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
...
With this code the Style defined in the Window.Resources is not being applied to the TextBlock inside the DataTemplate but it is on other TextBlocks on the Window.
If I copy the Style and set it in the DataTemplate resources like this:
<DataTemplate.Resources>
<Style TargetType="{x:Type TextBlock}" >
<Setter Property="FontSize" Value="28" />
<Setter Property="Margin" Value="3" />
<Setter Property="Foreground" Value="Green" />
</Style>
</DataTemplate.Resources>
Then it works. Any idea why do I need to duplicate the style?
Thanks in advance.
Implicit Styles will apply in templates only to types that inherit from System.Windows.Controls.Control and since TextBlock inherits directly from System.Windows.FrameworkElement it won't work. You have to either give your style x:Key and use it explicitly or declare your style in Application.Resources but then it will apply to all TextBlocks and by this I mean basically every displayed bit of text, in whole application
It's a WPF quirk. When a control doesn't inherit from Control, but directly from FrameworkElement, implicit style lookup inside a template skips directly to the application resources. If you put the style in the application resources (App.xaml) it would work.
Alternatively, you can use a named resource and BasedOn to reference it:
<DataTemplate.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource MyTextStyle}" />
</DataTemplate.Resources>
Please take a look DataTemplate and Style Confusion:
I posted this as a "bug" on Connect in October 2006.
...
"This behavior is 'By Design' and this is why. Templates are viewed as an encapsulation boundary. Elements produced by these templates fall within this boundary. And lookup for a style with a matching TargetType stops at this boundary. Hence the TextBlock in the repro which is produced through a template does not pick up the Style in question. Whereas the TextBlock defined outside the template does.
One way to work around this problem is to give an explicit name to the Style and reference the style by this name on the TextBlock within the template.
I have an element in my window, as below:
<Grid>
<DockPanel LastChildFill="True">
<Label Name="StatisticsLabel" DockPanel.Dock="Bottom"></Label>
<RichTextBox Style="{StaticResource FocusMode}" Name="RichTextBox1" />
</DockPanel>
</Grid>
I would like to swith between two styles at runtime depending of the state I need the control to be in.
I had assumed I could use the following code:
<Window.Resources>
<Style x:Name="FocusMode" TargetType="RichTextBox">
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"></Setter>
</Style>
<Style x:Name="NormalMode" TargetType="RichTextBox">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"></Setter>
</Style>
</Window.Resources>
Of course this isn't working.
Why does WPF not support multiple styles per element? Seems like a pretty basic requirement?
Otherwise, how do I achieve this?
Sorry figured it out, instead of x:Name use x:Key as below:
<Window.Resources>
<Style x:Key="FocusMode" TargetType="RichTextBox">
<Setter Property="VerticalScrollBarVisibility" Value="Disabled"></Setter>
</Style>
<Style x:Key="NormalMode" TargetType="RichTextBox">
<Setter Property="VerticalScrollBarVisibility" Value="Auto"></Setter>
</Style>
I'd have a look at style triggers. You can probably get a good start on the subject from this post: How to make Style.Triggers trigger a different named style to be applied