How to set one content to several buttons in WPF - c#

I have some buttons -in different windows- that have the same content. But if two windows surfaced together,out of the first window's button content disappears.
Buttons Style is :
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
button Code in windows is :
<Button Style="{DynamicResource BSaveBtn}" Template="{DynamicResource FlatGreenBtnHover}" />
problems occurs only with content -not another style properties- .

Seems to work fine for me when I tested it here.
A few things I noticed though that may help. You don't need them to be DynamicResource, they should really be StaticResource unless you plan on modifying them.
I assume you are declaring these in the Windows.Resource section or repeating them on each window?
If so you should centralize those to a ResourceDictionary.
Create a new Resource Dictionary put your style in there like so:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Then in your App.xaml put the following:
<ResourceDictionary>
<ResourceDictionary Source="MyResources.xaml" />
</ResourceDictionary>
The Image should really be in a dictionary to avoid loading it multiple times. Just add a line in that ResourceDictionary like so:
<BitmapImage UriSource="/login;component/Images/Save.png" x:Key="Save" PresentationOptions:Freeze="True" />
Setting the PresentationOptions:Freeze will also help if the image is never being modified.
Your call to the image would then change to be:
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="{StaticResource Save}"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
Once your resources are centralized in a ResourceDictionary (or multiple) it makes it easy to apply those same styles anywhere in your application and hopefully will help with your issue. If not please give more info on the problem you have such as sample code to make the issue happen please.

An instance of an element can only appear once in the visual tree. You can set the x:Shared attribute of the Style to False in order for a new instance of the StackPanel to get created for each Button to which you apply the style:
<Style TargetType="{x:Type Button}" x:Key="BSaveBtn" x:Shared="False">
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="70"/>
<Setter Property="Height" Value="68"/>
<Setter Property="Background" Value="{DynamicResource FlatGreen}"/>
<Setter Property="Template" Value="{DynamicResource FlatGreenBtnHover}"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Vertical" FlowDirection="RightToLeft">
<Image Width="30" Source="/login;component/img/buttonpic/save.png"/>
<TextBlock Text="save" FontSize="16" FontFamily="/login;component/fonts/#Droid Arabic Kufi" Foreground="White" HorizontalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>

Related

Remove Listview mouse over

I have a simple list view.
<ListView x:Name="DatabasesLstVw" ItemsSource="{Binding Path=Issues}"
ItemContainerStyle="{StaticResource removeMouseOverStyle}"
AlternationCount="2" Grid.Row="1" Margin="20,10,20,0"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
FontSize="12" FontWeight="Normal"
BorderThickness="0" Background="Transparent"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.Resources>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed" />
</Style>
</ListView.Resources>
<ListView.View>
<GridView >
<GridViewColumn Header="Message">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I have created a style trying to remove the default mouse over and select styling.
<Style x:Key="removeMouseOverStyle" TargetType="{x:Type ListViewItem}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent"></Setter>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0,0,0,0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontSize" Value="12"/>
</Trigger>
<Trigger Property="ItemsControl.IsMouseOver" Value="true">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="FontWeight" Value="Normal"/>
</Trigger>
</Style.Triggers>
</Style>
I cant post what its doing without trying to create a gif picture of it. Basically its hopping a little with the mouse over. First I thought it was setting margin , then tried padding and font size.
What exactly is this default mouse over doing and how do I remove it?
There could be many ways how they could have implemented selection\mouse over. For example often it is done by showing separate Border for every state. For control such simple as ListViewItem it's better to override it's ControlTemplate and do what you need there. You can use default control template, just remove triggers:
<Style x:Key="removeMouseOverStyle"
TargetType="ListViewItem">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border"
Padding="2"
SnapsToDevicePixels="true"
Background="Transparent">
<GridViewRowPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
With this style items won't change their appearence on selection or mouse over. Also, you can use base ItemsControl control - it does not have selection\mouse over behavior by default.

How to change Modern UI menu text to uppercase

I am using Modern UI with WPF to create a project. Main menu items appears to be lowercase, which is the one thing on theme I want to change. Is there any way to change it from my project's MainWindow.xaml or MainWindow.xaml.cs or any other file?
My code for menu is:
<mui:LinkGroup DisplayName="Home" >
<mui:LinkGroup.Links>
<mui:Link DisplayName="Dashboard" Source="/Pages/home.xaml" />
</mui:LinkGroup.Links>
</mui:LinkGroup>
FYI, I can change it from theme's code and build a new FirstFloor.ModernUI.dll file and use it. But that's not what I want, it will not be effective if I cannot override it after using one .dll. There must be a way, I must have missed it.
UPDATE
I have an image of the display window.
I do not have problem with DASHBOARD but what I want to do is change home to uppercase, or how I write on xaml code.
If you look at the source code for the MUI project there is a theme called ModernMenu.xaml (under Themes in the FirstFloor.ModernUI project).
You can simply add a style to your own application like the following. (I removed the converter that sets the text to lowercase and increased the spacing between first-line menu options so options that have more than one word are clearly separated from neighbouring options.)
<Style TargetType="controls:ModernMenu">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:ModernMenu">
<Grid>
<Grid.Resources>
<Style TargetType="ListBox" BasedOn="{StaticResource {x:Type ListBox}}">
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="16" />
</Grid.RowDefinitions>
<ListBox ItemsSource="{TemplateBinding VisibleLinkGroups}"
SelectedItem="{Binding SelectedLinkGroup, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="FontFamily" Value="Segoe UI Light" />
<Setter Property="Foreground" Value="{DynamicResource MenuText}" />
<Setter Property="FontSize" Value="23"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
<Setter Property="Margin" Value="0,0,25,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<TextBlock DataContext="{TemplateBinding Content}"
Text="{Binding DisplayName}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="{DynamicResource MenuTextHover}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="{DynamicResource MenuTextSelected}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<ListBox Grid.Row="1"
ItemsSource="{Binding SelectedLinkGroup.Links, RelativeSource={RelativeSource TemplatedParent}}"
SelectedItem="{Binding SelectedLink, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
VerticalAlignment="Top">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="Foreground" Value="{DynamicResource SubMenuText}" />
<Setter Property="FontSize" Value="11"/>
<Setter Property="Margin" Value="0,0,12,0" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid DataContext="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<TextBlock Text="{Binding DisplayName, Converter={StaticResource ToUpperConverter}}" TextAlignment="Center"/>
<TextBlock Text="{Binding DisplayName, Converter={StaticResource ToUpperConverter}}" FontWeight="Bold" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="{DynamicResource SubMenuTextHover}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="{DynamicResource SubMenuTextSelected}"/>
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
To do this you need a reference to the namespace at the top of your XAML file:
xmlns:controls="clr-namespace:FirstFloor.ModernUI.Windows.Controls;assembly=FirstFloor.ModernUI"
That should do the trick.
I have got the same problem metioned in the description above.
It seems to be that the ModernMenu which contains the links converts the DisplayName value to lower case.
With the help of Blend i found out that the basic ControlTemplate contains a TextBlock with a binding to the DisplayNameProperty.
<TextBlock.Text>
<Binding Path="DisplayName">
<Binding.Converter>
<mui:ToLowerConverter/>
</Binding.Converter>
</Binding>
</TextBlock.Text>
To solve this problem i have created a new ControlTemplate for the ModernMenu based on the basic ModernMenu ControlTemplate but without the BindingConverter.
Unfortunately this solution does not work because the whole control is not visible or get not painted when i define a custom ControlTemplate.
In my opinion there is no way at the moment to change the the Style of the DisplayNameProperty easily.. I spent a lot of hours to find a solution for the problem and every try failed in sprout..
Maybe a custom control which inherits from the ModernMenu and a new ControlTemplate based on the ModernMenu without that converter will be work..
I will test it in the next few days and post my experience with this attemp.

Setting the Header of GroupBox in a GroupBox style

I'm getting XAML parse exceptions when using a certain GroupBox Style more than once. I'm keeping the style in UserControl.Resources.
Here is an example of a simplified style that does not cause a XAML parse exception:
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header" Value="Hello World!" />
</Style>
Here is another one that does not cause a problem.
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header">
<Setter.Value>
Hello World!
</Setter.Value>
</Setter>
</Style>
This one however does cause a problem:
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="Hello World!" />
</Setter.Value>
</Setter>
</Style>
Again, it's only a problem when I use the style on more than one GroupBox. If I use it just once, I don't get the XAML parse exception. And it doesn't have to be just a TextBlock. I think it's any UIElement.
Any ideas? Thanks!
You cannot set the content of the header to another UI control in the style. Try creating a datatemplate.
<Window.Resources>
<Style x:Key="MyGroupBoxStyle" TargetType="GroupBox" BasedOn="{StaticResource {x:Type GroupBox}}">
<Setter Property="BorderThickness" Value="5" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="Hello World!!!!!!"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel>
<GroupBox Style="{StaticResource MyGroupBoxStyle}" Height="200" Width="200"/>
<GroupBox Style="{StaticResource MyGroupBoxStyle}" Height="200" Width="200"/>
</StackPanel>

wpf default style and style base

I'm trying to make a wpf style that will allow me to:
1. Base alternate styles off a base style
2. Have the base style be a default that every control uses when no style is applied.
For example, I have code to make style for a button...
<!--Base Button-->
<Style TargetType="Button" x:Key="BaseButton">
<Setter Property="Width" Value="auto"/>
<Setter Property="MaxWidth" Value="100"/>
<Setter Property="Height" Value="auto"/>
<Setter Property="MaxHeight" Value="50"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".85"/>
</Trigger>
</Style.Triggers>
</Style>
<!--Apply Base to any Button without a style-->
<Style TargetType="Button" BasedOn="{StaticResource BaseButton}"/>
and here is a style for a specific button...
<Style TargetType="Button" x:Key="DeleteBtn" BasedOn="{StaticResource BaseButton}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="35"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="(some url)" Height="16" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Label Content="Delete" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
As you can see, I would like to be able to base the "DeleteBtn" Style off of the base, but also have the base be the default for every button placed on the screen that doesn't have a specific style set. This currently only works for buttons and no other control. The above example does work, but I can't seem to do the same thing for labels, textboxes etc. Any thoughts or input would be greatly appreciated :)
Here's an example of one that doesn't work..
<!--Base Icon-->
<Style TargetType="Image" x:Key="BaseIcon">
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Right"/>
</Style>
<!--Apply Base to any Icon without a style-->
<Style TargetType="Image" BasedOn="{DynamicResource BaseIcon}"/>
It gives an error: 'DynamicResourceExtension' cannot be set on the 'BasedOn' property of type 'Style'. A 'DynamicResourceExtension' can only be set on a DependencyProperty of a DependencyObject.
Your example only works for Buttons because your "base" style is targeting buttons only.
i.e.
TargetType="Button"
You can try creating a style that targets the parent FrameworkElement instead. Just be warned that not all properties are supported. Some properties are unique to the child control.
It works for me, just tested it.
<Window.Resources>
<Style TargetType="Label" x:Key="BaseLabel">
<Setter Property="Background" Value="Red"/>
<Setter Property="HorizontalContentAlignment" Value="Right"/>
</Style>
<Style TargetType="Label" BasedOn="{StaticResource BaseLabel}"/>
</Window.Resources>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom" Orientation="Horizontal">
<Label Width="100" Content="TestLabel1"/>
<Label Width="100" Content="TestLabel1" Foreground="White"/>
</StackPanel>
</Grid>
Edit: Added derived right alignment for fun.

Use a ContentPresenter for personnalize a template

I created a ressourceDictionnary for creating a templateButton.
I would like to be able to change the png image when i use this template, i think i need to use a ContentPresenter, but i don't know why.
Here is my RessourceDictionnary :
<ControlTemplate TargetType="{x:Type Button}" x:Key="BoutonRessources">
<Button Width="32" Margin="0,0,7,0" Name="tbrClear" ToolTip="Clear" VerticalAlignment="Center" BorderThickness="0" HorizontalAlignment="Center" Background="Transparent" HorizontalContentAlignment="Center">
<Border>
<Image Source="xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png" Height="18"/>
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="BoutonToolbarSelected.png"/>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="22"/>
<Setter Property="Width" Value="32"/>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
</Border>
</Button>
So, when i use this Button template, i would like to be able to pass them an other png image to display. For example i would like to replace xRtDiva_XWPF_TBR_PREMIER.PNG_IMAGES.png by MyPicture.png.
How doing this ? With a contentPresenter ?
Thanks :)

Categories

Resources