WPF: Restyle all controls with scroll bars - wpf

How can I change the style -ONCE- for the scrollbars shown by all controls (listbox, treeview, scrollbarviewer, richtextbox, etc...)?

If you will define your Style for a control with no x:Key attribute, it will be applied for all instances of that control.
Try like this:
<Window.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="Red"/>
</Style>
</Window.Resources>
<Grid>
<TextBox Margin="24,12,0,0" VerticalScrollBarVisibility="Visible" AcceptsReturn="True" Height="28" VerticalAlignment="Top" HorizontalAlignment="Left" Width="89" />
<ScrollBar Name="scroll" HorizontalAlignment="Right" />
</Grid>
Here you can see that the Style is defined for ScrollBar control and have no x:Key attribute defined so it gets applied to the each ScrollBar instance within Window. Like ScrollBar of TextBox and ScrollBar named scroll also.
Hope this helps!

Thanks. Finally the problem was solved by setting the style in the Themes/Generic.xaml and (because of custom controls existing in another assembly with they respective resources merged) adding the following to App.xaml...
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Generic.xaml"/>
<ResourceDictionary Source="MyCtls/MyRes.xaml" />
</ResourceDictionary>
</Application.Resources>
The key point is to merge the Generic.xaml file.
Also, if the resource dictionary is in another assembly, it must be referenced as...
<ResourceDictionary Source="pack://application:,,,/OtherAssembly;component/MyCtls/MyRes.xaml"/>

Related

Default Styling for text blocks in an MVVM application

I have run across a problem when overriding default styles in an MVVM . I am trying to change the default foreground value of all of the text in my application. This works until I have Text Blocks in UserControls. These Text Blocks do not inherit from the default, unlike the other controls such as Labels.
I have created a small example for this.
I have a generic Resource dictionary declared. This is holding the default styles.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1.Resources">
<Style TargetType="Label">
<Setter Property="Foreground"
Value="Blue" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground"
Value="Red" />
</Style>
This resource dictionary is merged into the MainWindow.
<Window>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type vm:UserControlViewModel}">
<v:UserControl1 />
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<Grid>
<Label>Main Window Label</Label>
<TextBlock Grid.Column="1">Main Window Text Block</TextBlock>
<ContentPresenter Content="{Binding Content}" />
</Grid>
</Window>
In my simple example I have a generic MainViewModel set to the DataContext of the MainWindow.
public class MainViewModel
{
public UserControlViewModel Content { get; set; }
public MainViewModel()
{
Content = new UserControlViewModel();
}
}
The user control viewmodel is simply a shell with no properties that need to be displayed. However the user control itself is just a simple label and text block like the Main Window
<UserControl>
<Grid>
<Label>UserControl Label</Label>
<TextBlock >User Control Text Block</TextBlock>
</Grid>
</UserControl>
The weird part is the override for the Label works properly and the Text Block does not. This is the picture of the end result.
Why does the Text Block in the user control not use the default style that is applied to the Text Block?

Reset Style in certain portion of Visual Tree in WPF

I am setting some global styles for TextBox, ComboBox, TextBlock, etc. in my App.xaml file. I want these styles to flow down through the visual tree for a consistent look and that is what they are doing.
However, I am using a Ribbon in part of my UI. The style customizations are completely throwing off the appearance of the Ribbon. The ribbon sits at the same level as many other UI elements so is there a way to just reset the style for the ribbon and its visual children
I don't think that you can change this wpf behaviour.
But you can try to contain all global styles to specific resource dictionary and use it in all other VisualTree elements.
Or you can try something like this:
<Window ...>
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<DockPanel LastChildFill="True">
<Button x:Name="button1" Content="button" DockPanel.Dock="Top" />
<StackPanel>
<StackPanel.Resources>
<Style TargetType="Button">
</Style>
</StackPanel.Resources>
<Button x:Name="button2" Content="lala" />
</StackPanel>
</DockPanel>
</Window>
Element with name "button2" will be default.

Why does TextBox get a padding when Grid.Margin is set in App.xaml?

A simple window:
<Window x:Class="MyApp.MainWindow" xmlns="..." xmlns:x="...">
<Window.Resources>
<Style TargetType="Grid">
<Setter Property="Margin" Value="8"/>
</Style>
</Window.Resources>
<Grid>
<TextBox VerticalAlignment="Top" HorizontalAlignment="Left">Test</TextBox>
</Grid>
</Window>
It looks like this:
Now we remove Window.Resources:
<Window x:Class="MyApp.MainWindow" xmlns="..." xmlns:x="...">
<Grid>
<TextBox VerticalAlignment="Top" HorizontalAlignment="Left">Test</TextBox>
</Grid>
</Window>
And add the style definition to App.xaml:
<Application x:Class="MyApp.App" xmlns="..." xmlns:x="..." StartupUri="View\MainWindow.xaml">
<Application.Resources>
<Style TargetType="Grid">
<Setter Property="Margin" Value="8"/>
</Style>
</Application.Resources>
</Application>
Strangely, the TextBox now gets a padding:
Why?
Implicit Styles for elements that do not derive from Control (i.e. Grid) will be applied to all instances of that control when placed in the Application resources. But they will not be applied to certain instances when the Style is placed any where else.
Effectively, elements inside ControlTemplate are except from implicit Styles for their type, unless that Style is defined in application resources.
Since Grid is not a control (i.e. it doesn't derive from Control), placing it's Style in the application resources will affect every Grid in your application. This includes Grids defined in the ControlTemplate of controls, like TextBox.
More information can be found here.
I suppose the default content of textbox contains a grid while placing the inner content. When in application resources, the TextBox styling occurs, the Grid Style also gets applied to the Grid inside the TextBox.
But when the same Grid style is applied in window resources (i.e after global styling occurs), it does not affect the Grid inside the TextBox.

Problem in Databinding to Image Source WPF

I have some problem on databinding to Image's Source Property.
I have a ListView Template
<Style x:Key="ListViewStyle" TargetType="{x:Type ListView}">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate x:Key="ListViewItemTemplate">
<StackPanel Width="60" Margin="5,5,10,5">
<Image Height="40" Width="40" Source="{Binding XPath=#Image}"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding XPath=#Name}" TextAlignment="Center"
TextWrapping="Wrap" FontWeight="bold"
HorizontalAlignment="Center" Margin="0,0,0,1" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
This Style is defined in a Resource Dictionary File which is added in app.xaml. (So is accessible anywhere).
Now I have a window in which I have used this style for ListVew.
In WindowResources I have created an xmldatasource provider:
<XmlDataProvider x:Key="MyData" XPath="/Reports">
<x:XData>
<Reports xmlns="">
<Item Name = "Item1" Image="Resources\MenuIcons\Pic1.png"/>
<Item Name = "Item2" Image="Resources\MenuIcons\Pic2.png"/>
<Item Name = "Item3" Image="Resources\MenuIcons\Pic3.png"/>
</Reports>
</x:XData>
</XmlDataProvider>
and I have assigned this datasource as ItemsSource for Listview:
<ListView Name="MyListView" Style="{DynamicResource ListViewStyle}"
ItemTemplate="{StaticResource ListViewItemTemplate}"
ItemsSource="{Binding Source={StaticResource MyData},XPath=Item}"/>
My Problem is when I run application ListViewItem's Text is displaying, but Image is missing..
But When I defined this Style inside Window.Resource and used Style as StaticResource instead of Dynamic Resource, everything works fine.
Can Anybody tell me reason for not desplaying Image? I want to use this style globally(So I need to define it in ResourceDictionary). Can anyone help me?
I think nobody has answered your question yet because we couldn't see anything wrong.
I decided to try to reproduce your problem, but your code worked perfectly even though I tried to follow your repro steps.
Here are my steps:
Created a blank WPF Application
Added a ResouceDictionary file Dictionary1.xaml
Pasted your <Style> code into Dictionary1.xaml inside the <ResourceDictionary> tag
Edited out the typo where you set an x:Key on the DataTemplate
Added <Window.Resources> element to the top of Window1.xaml
Pasted your <XmlDataProvider> code into the <Window.Resources> tag
Replaced image pathnames, eg Image="Resources\MenuIcons\Pic1.jpg" became Image="TestImage.jpg"
Pasted your <ListView> code into the <Grid> tag
Removed your bogus ItemTemplate value, presuming this was left over from old code
Merged the dictionary "Dictionary1.xaml" into the Application's dictionary in App.xaml
Here is the relevant markup from App.xaml:
<Application
...>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
When I ran the application I saw a ListBox containing images with text underneath.
At this point I suggest you try reproducing my steps and see if your example works or not. If it does, try slowly changing things to be like your app that is not working. At some point you will discover what it is about your app that makes the difference. Then maybe we can give you some better advice how to fix it.
Hmm.. I found the problem... Problem was My Style Dictionary File and Images were in 2 separate directories in Project Directory. I saved All Dictionary Files in Styles Directory and all images in Resources Directory which is outside Styles Directory.
So I need to change Image path in xml as
<XmlDataProvider x:Key="MyData" XPath="/Reports">
<x:XData>
<Reports xmlns="">
<Item Name = "Item1" Image="..\Resources\MenuIcons\Pic1.png"/>
<Item Name = "Item2" Image="..\Resources\MenuIcons\Pic2.png"/>
<Item Name = "Item3" Image="..\Resources\MenuIcons\Pic3.png"/>
</Reports>
</x:XData>
</XmlDataProvider>
(I should Add ..\ before path) This solved my problem.. Thanks Ray Burns for your reply.. – Sasikumar D.R. 0

Strange Style Behaviour in wpf?

Ok, I was programming an app that loaded merged dictionaries on runtime to change appearance and behaviour when I got stuck : some of the controls on my forms just weren't reacting to the styles I thought they had to react to.
I have tried to simplify the problem as much as I could and came up with something so simple that I'm afraid I am overlooking the bleeding obvious, but anyway here it goes :
<Window x:Class="Example.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="100" Width="50">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Green"></Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<TextBox Text="1" Name="box1"/>
<TextBox Text="2" Name="box2"/>
<TextBox Text="3" Name="box3"/>
</StackPanel>
</Window>
The question is : why is the first textbox not green?
==> that is, the designer shows it in green, but when running the app, it is no longer...
I know the solotion to this particular problem is to remove the merged dicitonary tags, but I need to know how to solve this using merged dictionaries.
Thanks!
MergedDictionaries have always been quirky, you can set any resources you want in them, but they only process outside resource dictionary references at runtime.
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="StylesDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
The only requirement is that the resources be set in an other dictionary.
Try this...
<Style TargetType="{x:Type TextBox}">
I'm not sure if this will work, but when I was having styling problems, I fixed them by using
TargetType="{x:Type TextBox}"

Resources