Swapping Foreground and Background Colors - xaml

I have a button, and when the mouse goes over it, I'd like to swap the foreground and background colors. (The original foreground and background are inherited from the parent control.) I have written the code below:
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Mode=OneTime}"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
But when the mouse moves over the button, the entire element goes black! Is there a way to force the one time binding on Background to finish before Foreground is set to black (sequentially)?

Related

XAML DataGrid triggering style from other elements

(Note: The Snipping Tool has hidden the mouse cursor hovering over Amelia Earhart in this screen grab.)
When the mouse is RowHeader.IsMouseOver=True then the style is triggered and in this example the font is set to Bold and Italic and the colours change.
Problem: I want to call the same trigger when I Click or Mouseover on any DataGridCell in the row. So if I click on the cell "Hello World" then the RowHeader "Amelia Earhart" is formatted.
<DataGrid.RowHeaderStyle>
<Style TargetType="DataGridRowHeader">
<Setter Property="Width" Value="25"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<!-- I want to trigger this IsMouseOver from DataGridCell.IsMouseOver -->
<Label Content="{Binding [0]}" FontSize="10" Margin="0" >
<Label.Style>
<Style x:Name="sOne" TargetType="Label">
<Setter Property="Foreground" Value="WhiteSmoke"/>
<Setter Property="Background" Value="CadetBlue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Foreground" Value="Cyan"/>
<Setter Property="Background" Value="Navy"/>
</Trigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowHeaderStyle>

AvaloniaUI Styles-pseudoclasses

I'm trying out styles in avalonia and most works, except for pseudoclasses, they just get ignored.
I have created a window and all styles are in there and I have created a user control (with a button on - the pseudoclasses are on the button), using the styles. I do not use code, only xaml to define the styles.
I have tried it out in the "Style Selector" for the button as "Button:pseudoclassname" and "Button.le:pseudoclassname". I have also tried "Button:pointerover" and "Button:hover" as the documentation mentions that that could be modified. No result. The styles for the pseudoclasses are all ignored, the others are all executed correct.
Is there something I'm doing wrong or is this a bug in avalonia ?
The xaml windows file:
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:Hub.Views"
xmlns:vm="using:Hub.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Hub.Views.MainWindow"
Icon="/Assets/avalonia-logo.ico"
Width="200" Height="300"
Title="Hub"
Classes="le">
<Window.Styles>
<Style Selector="Window.le">
<Setter Property="Background" Value="#191919"/>
</Style>
<Style Selector="Button.le">
<Setter Property="Background" Value="green"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="Button.le:pointerover">
<Setter Property="Background" Value="red"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="Button.le:pressed">
<Setter Property="Background" Value="blue"/>
<Setter Property="Foreground" Value="white"/>
</Style>
<Style Selector="TextBlock.le_update">
<Setter Property="FontStyle" Value="Italic"/>
<Setter Property="FontSize" Value="17"/>
<Setter Property="FontFamily" Value="Arial, Verdana"/>
<Setter Property="Foreground" Value="white"/>
<Setter Property="Background" Value="transparent"/>
</Style>
</Window.Styles>
<views:UpdateView/>
</Window>
The xaml user control file:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Hub.Views.UpdateView">
<DockPanel>
<StackPanel DockPanel.Dock="Bottom">
<Button Classes="le" HorizontalAlignment="Center" HorizontalContentAlignment="Center" Width="300">
Check for updates
</Button>
</StackPanel>
<StackPanel Spacing="5" Margin="5">
<TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
No updates for Hub.
</TextBlock>
<TextBlock Classes="le_update" HorizontalAlignment="Center" Margin="4">
No updates for Engine.
</TextBlock>
</StackPanel>
</DockPanel>
</UserControl>
Button's Background property does get affected by your style, but at that point it has no effect on the actual Button's background, because Background property controls only the normal state of the button.
If you take a look at the default Button style here you can see that it passes its background to ContentPresenter via TemplateBinding:
<Setter Property="Template">
<ControlTemplate>
<ContentPresenter x:Name="PART_ContentPresenter"
Background="{TemplateBinding Background}"
but overrides ContentPresenter's background in a style like this:
<Style Selector="Button:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource ButtonBackgroundPointerOver}" />
Since it's ContentPresenter that actually draws the background (Button is a lookless control), you'll see the button to have ButtonBackgroundPointerOver and not the Button's Background property value.
So, you need to write a style that changes the inner ContentPresenter like this:
<Style Selector="Button.le:pointerover /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="green" />
</Style>
Unfortunately that makes your styles theme-dependent since control templates are different between default and fluent themes.
The answer Kekekeks gave is the correct one for the question I asked.
However, I use this space in the hope to help novice users of avalonia with no background in xaml at all, like I do. Most of us look at avalonia to give our apps an interface that works on Windows/Mac/Linux. To be honest, at the moment of writing, no real alternatives in c# exist.
At this moment Avalonia does have examples and some documentation that is good, but not so for people not really having a background in xaml.
Therefore, go to Udemy or LikedIn.Learning or Youtube or wherever you find a good course on WPF AND AFTER THAT go to the documentation of Avalonia and start playing around.
The similarities that both (Avalonia and WPF) share is enormous !!! And yes it is mentioned a few times in the docs, but a blunt "Do go and learn WPF first if you are new to xaml !" on the frontpage of the documentation would have saved me a fair share of time in trying to find it all out via the website.
Fair is fair, the project still is in beta and the website is already well documented for that stage, so no blame to the team !

Style trigger from parent control

Is it possible to use a style trigger from another control?
I have Border control which lives in the indicator part of each row of a grid (the indicator is the part on the very left with the little arrow). I want to set the background depending if the row is selected. So I created a style:
<controls:SelectionConverter x:Key="SelectionConverter" />
<Style x:Key="SelectionStyle" TargetType="Border">
<Setter Property="Background" Value="{Binding Converter={StaticResource SelectionConverter}}"/>
<Style.Triggers>
<!-- here I want to have a trigger which reacts on a property of the grid control -->
</Style.Triggers>
</Style>
The border control then will use the style (in fact there are 3 border controls).
The SelectionConverter will return the correct color depending on the row (that works fine).
The problem is that the background is not updated when I select a different cell (which does make sense, because there is no trigger when to update it).
Is it possible to setup a trigger of the parent control?
Something alone the line
<Trigger Property="ParentControl.SelectionHasChanged" Value="True"></Trigger>
You should be able to use ElementName in your Binding to achieve this. For example, the following binds to the IsEnabled property of a Grid and sets the Background property of the Border to red when this is true:
<Grid x:Name"main_grid">
...
<controls:SelectionConverter x:Key="SelectionConverter" />
<Style x:Key="SelectionStyle" TargetType="Border">
<Setter Property="Background" Value="{Binding Converter={StaticResource SelectionConverter}}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsEnabled, ElementName=main_grid}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
...
</Grid>

xaml listview how to disable space for scroll?

I working on a metro app and I am using listview
listview automatically puts some space on right side for scroll. In my code there is no need for scrolling
I tried to disable it ScrollViewer.VerticalScrollBarVisibility="Disabled" or scrollmode=false but the space allways appears
is there a way I could disappear it because listview highlights on over and click mode and it looks bad
Create a copy of the current ListView Style by selecting Edit Additional Templates -> Edit Generated Item Container -> Edit a Copy (see screenshot below).
In the template copy, modify the Margin (last line shown below)
<Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Margin" Value="0,0,18,2"/>
to
<Setter Property="Margin" Value="0" />
You'll also need to set ScrollViewer.VerticalScrollBarVisibility="Hidden" on the ListView itself (like you tried before(, or you can get adventurous and modify the template for the ListView itself (Edit Template) and remove the ScrollViewer and set the ItemsPanelTemplate to just StackPanel from VirtualizingStackPanel.

Switching between styles in Storyboard to receive blinking LED

I have a simple Ellipse. On its "Fill" Property i attached a RadialGrientBrush, which makes it look like an "LED"
I may change the Fill Property in a DataTrigger without problems.
But on some Data Values, i want to have a blinking LED. it shall switch continuously between my Black RadialGradientBrush and my Red RadialGradientBrush.
I found some Animation Syntax but none of them works, i dont want a smooth animation, i just want to switch the Fill property in an infinite loop.
this is my "normal" way to set my style:
<Ellipse ...>
<Ellipse.Ressources>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=someproperty, Mode=OneWay}" Value="on">
<Setter Property="Fill" Value="{StaticResource GreenLEDBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Ellipse.Ressources>
</Ellipse>
and now my approach was:
<DataTrigger Binding="{Binding Path=shallblink, Mode=OneWay}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
I was not able to get what i want...
Maybe someone may help?