ItemContainerStyle for RibbonGroup - c#

I'm trying to bind a RibbonGroup and a couple of RibbonButtons to my viewmodel with the following xaml:
<Style TargetType="{x:Type ribbon:RibbonGroup}" x:Key="RibbonGroupStyle">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="ItemContainerStyle" Value="{DynamicResource RibbonButtonStyle}" />
<Setter Property="ItemsSource" Value="{Binding Buttons}" />
</Style>
<Style TargetType="{x:Type ribbon:RibbonButton}" x:Key="RibbonButtonStyle">
<Setter Property="Label" Value="{Binding Header}" />
</Style>
This gives me the following error, which I can understand, but how do I properly bind the Label of the RibbonButton to my viewmodel?
A style intended for type 'RibbonButton' cannot be applied to type 'RibbonControl'.

You can place one style inside the other and apply it to every button:
<Style TargetType="{x:Type ribbon:RibbonGroup}" x:Key="RibbonGroupStyle">
<Style.Resources>
<Style TargetType="{x:Type ribbon:RibbonButton}" BasedOn="{StaticResource {x:Type ribbon:RibbonButton}">
<Setter Property="Label" Value="{Binding Header}" />
</Style>
</Style.Resources>
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="ItemsSource" Value="{Binding Buttons}" />
</Style>

Related

Why can't I override the default BasedOn Style? WPF

I have a default Label Style
<Style x:Key="LabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Style BasedOn="{StaticResource LabelStyle}" TargetType="{x:Type Label}" />
I then try to use a different style for a single Label
<Style x:Key="HeaderLabelStyle" TargetType="{x:Type Label}">
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<Label Content="Text here" Name="someName" Style="{StaticResource HeaderLabelStyle}"/>
But for some reason the label always gets the default style. Why? Can this be overridden?
Thanks
So I realised that the default (string) template for Label is an indented TextBlock (styles are inherited)
Since I also was defining a global style for TextBlock
<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
No matter how many types of Label I had I was always bound to use the template for TextBlock
So the solution was to define a dummy TextBlock class
namespace Theme
{
public class HeaderTextBlock : TextBlock
{
}
}
Then assign it its own global style
xmlns:this="clr-namespace:Theme"
<Style x:Key="HeaderTextBlockStyle" TargetType="this:HeaderTextBlock">
<Setter Property="Foreground" Value="{StaticResource HeaderForegroundBrush}" />
<Setter Property="FontSize" Value="13.333" />
<Setter Property="FontFamily" Value="Segoe UI" />
</Style>
<Style BasedOn="{StaticResource HeaderTextBlockStyle}" TargetType="{x:Type this:HeaderTextBlock}" />
And use TextBlocks instead of Labels (haven't figured out how to implement a Label child yet since (Label : TextBlock) = false
xmlns:theme="clr-namespace:Theme;assembly=Theme"
<theme:HeaderTextBlock Text="Some text" Name="titleLabel" Style="{StaticResource HeaderTextBlockStyle}"/>

wpf create style for named element

Is it possible to add style to xaml element without editing the element?
for example:
xaml element:
<Grid>
<Grid x:Name="A">content A</Grid>
<Grid x:Name="B">content B</Grid>
</Grid>
and style:
<Style x:Key="StyleForA" TargetName="A" TargetType="{x:Type Grid}" >
<Setter Property="Background" Value="Red"/>
</Style>
<Style x:Key="StyleForB" TargetName="B" TargetType="{x:Type Grid}" >
<Setter Property="Background" Value="Green"/>
</Style>
UPD:
I have a project with a lot of styles (aero, black, etc ).
And if I edit the element Style="{StaticResources StyleForA}" I must edit all styles.
So I need to create local style that affected to named element.
Natively you can't.
But without touching your XAML, you can do it very easily using code :
Grd1.Style = (Style) this.Resources["GridKey"];
Pure XAML approach using Blend behaviors,
<Grid x:Name="Grd1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ic:ChangePropertyAction PropertyName="Style" Value="{DynamicResource GridKey}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
Yes. I use this style on my App.xaml to add a teplate around all aplication controls with error:
<Style x:Key="BordaTemplate" TargetType="Control">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<Border BorderBrush="Red" BorderThickness="1">
<AdornedElementPlaceholder Name="myControl"/>
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="PasswordBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="DataGrid" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="ListBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="CheckBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="ComboBox" BasedOn="{StaticResource BordaTemplate}" />
<Style TargetType="DatePicker" BasedOn="{StaticResource BordaTemplate}" />
Not like as you have defined using target but if you want to apply a style to a specific control. then use below:
<StackPanel>
<Button x:Name="A">
<Button.Resources>
<Style TargetType="{x:Type Button}" >
<Setter Property="Background" Value="Red"/>
</Style>
</Button.Resources>
content A</Button>
<Button x:Name="B">
<Button.Resources>
<Style TargetType="{x:Type Button}" >
<Setter Property="Background" Value="Green"/>
</Style>
</Button.Resources>
content B</Button>
</StackPanel>
Or probably create a base style and then create a BasedOn style for your controls.
Update: If you only want to be concerned about the style at a time and be sure of impacted elements:
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="First" >
<Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="{x:Type Button}" x:Key="Second" >
<Setter Property="Background" Value="Green"/>
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="A">
<Button.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource First}" />
</Button.Resources>
content A</Button>
<Button x:Name="B">
<Button.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource Second}" />
</Button.Resources>
content B</Button>
</StackPanel>
I think you can have a default style and you can override the properties you want on your local style.
<Grid>
<Grid.Resources>
<Style TargetType="Button" x:Key="Default">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="Foreground" Value="Blue"/>
</Style>
<Style x:Key="StyleForA" BasedOn="{StaticResource Default}" TargetType="Button" >
<Setter Property="Background" Value="Red" ></Setter>
</Style>
<Style x:Key="StyleForB" BasedOn="{StaticResource Default}" TargetType="Button" >
<Setter Property="Background" Value="Green" ></Setter>
</Style>
</Grid.Resources>
<StackPanel>
<Button Style="{StaticResource StyleForA}" Width="100" x:Name="A" Click="Button_Click" Height="100">Test A</Button>
<Button Style="{StaticResource StyleForB}" Width="100" x:Name="B" Click="Button_Click" Height="100">Test B</Button>
</StackPanel>
</Grid>

Set tooltip max width style

Ok, i know my question might be super dumb- but i couldn't find the solution my self- so here i am- asking your help:
in wpf i have a DataGrid with different styles.
now, i need to set the tooltip max width.
this is my DataGridCell style:
<Style TargetType="DataGridCell" x:Key="MyDataGridCellStyle">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
<EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
</Style>
how do i add to the tooltip the max width style?
Try this please
Keep this code
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
and add this to your datagrid
<DataGrid.Resources>
<Style TargetType="ToolTip">
<Setter Property="MaxWidth" Value="20" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{TemplateBinding Content}" >
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
Is what you tried to put your tooltip in a textblock
<Setter Property="ToolTip">
<Setter.Value>
<TextBlock MaxWidth="..." TextWrapping="Wrap" Text ="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
</Setter.Value>
</Setter>

Binding Failure on ToolBar Dragging

I have have a ToolBar which I am styling using the code shown below. I have come across three problems with the my ToolBar styling:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org">
<Style x:Key="ToolBarToggleButton" TargetType="{x:Type ToggleButton}"
BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Setter Property="Icon" Value="{Binding Icon}"/>
<Setter Property="ToolTip" Value="{Binding FullToolTip}" />
<Setter Property="ToolTipService.IsEnabled" Value="{Binding HasToolTip}" />
<Setter Property="IsChecked" Value="{Binding IsChecked}" />
<Setter Property="cal:Action.Target" Value="{Binding}" />
<Setter Property="cal:Message.Attach" Value="{Binding ActionText}" />
</Style>
...
First:
The tool bar images are currently getting used as a single static instance. Even with the property x:Shared="False" moving the ToolBar one over another will cause a rendering failure.
Solution:
In the ToolTip Styles.xaml, include the image source as a ContentTemplate
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org">
<Style x:Key="ToolBarToggleButton" TargetType="{x:Type ToggleButton}"
BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image x:Shared="false" Source="{Binding Icon}">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" />
<Setter Property="Stretch" Value="Fill" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="{Binding FullToolTip}" />
<Setter Property="ToolTipService.IsEnabled" Value="{Binding HasToolTip}" />
<Setter Property="IsChecked" Value="{Binding IsChecked}" />
<Setter Property="cal:Action.Target" Value="{Binding}" />
<Setter Property="cal:Message.Attach" Value="{Binding ActionText}" />
</Style>
<Style x:Key="ToolBarButton" TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image x:Shared="false" Source="{Binding Icon}">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Width" Value="16" />
<Setter Property="Height" Value="16" />
<Setter Property="Stretch" Value="Fill" />
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="{Binding FullToolTip}" />
<Setter Property="ToolTipService.IsEnabled" Value="{Binding HasToolTip}" />
<Setter Property="cal:Action.Target" Value="{Binding}" />
<Setter Property="cal:Message.Attach" Value="{Binding ActionText}" />
</Style>
</ResourceDictionary>
Now we have:
No other changes required.
Second:
The same dragging procedure the ToolTip and ToolTipService bindings also get corrupted - at this stage I am not sure of the underlying reason. The quick solution is to do what I have done with the image above and add the ToolTip to the Image. However, this causes the ToolTip only to show when over the Image and not when hovering over the very edge of the button.
Partial Solution:
Add the ToolTip to the Image. However, this is not ideal as then the tool tips do not show when on the very edge of the button.
Third:
When the drag operation shown above occurs, this also breaks the Caliburn property bindings
<Setter Property="cal:Action.Target" Value="{Binding}" />
<Setter Property="cal:Message.Attach" Value="{Binding ActionText}" />
Questions: (Second and Third Problem)
How to fix the problem with the ToolTip rendering?
How to fix the problem with the Caliburn property binding?
Thanks for your time.
Solution:
"I've finally fixed this. As near as I can tell, when you initiate a drag on a toolbar, any toolbar items on other toolbars which are covered by the toolbar you're dragging get removed from their current position in the visual tree, and then (presumably) added back when they're made visible again.
When they're removed from the visual tree (again, that's what I think is happening), they also lose access to the ToolBarToggleButton and ToolBarButton styles, because those are defined in the Styles.xaml resource dictionary which is added in ToolBarsView.xaml.
However, if you define those same styles globally, then it works - presumably, even though they're no longer children of ToolBarsView, they still have access to the global resources.
So... I've added a new property, IModule.GlobalResourceDictionaries, which allows each module to declare any resource dictionaries that should be added at the global scope. The ToolBars module makes use of this."
https://github.com/tgjones/gemini/issues/67#issuecomment-60040008
Try to re-assign the tooltips as a style trigger for the mouse over event such as:
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ToolTip" Value="{Binding FullToolTip}" />
<Setter Property="ToolTipService.IsEnabled" Value="{Binding HasToolTip}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="ToolTip" Value="{Binding FullToolTip}" />
<Setter Property="ToolTipService.IsEnabled" Value="{Binding HasToolTip}" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>

Style list item based on its property

I am pretty new to WPF and I am trying to build a quite simple application using MVVM light.
In my MainWindow.xaml (view) I have this :
<ListBox ItemsSource="{Binding InstalledVersions}"
ItemTemplate="{StaticResource VersionsDataTemplate}"
Style="{StaticResource VersionsStyle}"
ItemContainerStyle="{StaticResource VersionItemStyle}"/>
Where InstalledVersions is a list of InstalledVersionViewModel
In my MainWindowResources.xaml I have this (simplified) :
<DataTemplate x:Key="VersionsDataTemplate"
DataType="{x:Type viewmodels:InstalledVersionViewModel}">
<Grid>
<TextBlock Text="{Binding VersionNumber}" />
<TextBlock Text="{Binding FolderPath}" />
</Grid>
</DataTemplate>
<Style x:Key="VersionsStyle"
TargetType="{x:Type ListBox}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style x:Key="VersionItemStyle"
TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="White" />
</Style>
I wish to have a different background depending on the "IsActive" property of my InstalledVersionViewModel.
I tried to add this (as well as several variations of it) to my VersionItemStyle but (as I suspected, mostly because I don't understand what I'm doing) it doesn't work :
<Style.Triggers>
<Trigger Property="{Binding Path=DataContext.IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewmodels:InstalledVersionViewModel}}}" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
Thanks !
Since IsActive is part of view model against each row you can achieve that with DataTrigger
<Style x:Key="VersionItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>

Categories

Resources