banner



How To Change Foreground And Background In Html When You Move Mouse Over It

  • Remove From My Forums

 locked

Change foreground color dynamically based on groundwork colour

  • Question

  • Trouble domain: In my WPF application, I alter groundwork of lot of UI controls like Button or ListItems dynamically based on data they comprise. The background is changed either when the control is loaded or based on use activity/data received.

    Trouble statement: If the groundwork is too nighttime (Green/Blueish) I desire to set up the foreground to white else black.

    Constraints: I take a big application and performance is a major concern. That's why I am hesitant to use converters and am looking for some xaml/fashion trigger based solutions as this is but a condition based event.

    Solutions tried: To go along it simple, I am explaining what I tried for a unproblematic wpf button:

    <UserControl.Resources> <Fashion x:Central="NoChromeButton" TargetType="{x:Type Button}">         <Setter Property="Background" Value="{Binding Background}"/>         <Setter Holding="OverridesDefaultStyle" Value="True"/>         <Setter Belongings="BorderThickness" Value="1"/>         <Setter Property="BorderBrush" Value="White"/>         <Setter Belongings="HorizontalContentAlignment" Value="Middle"/>         <Setter Property="VerticalContentAlignment" Value="Center"/>         <Setter Holding="Padding" Value="1"/>         <Setter Property="Template">             <Setter.Value>                 <ControlTemplate TargetType="{x:Blazon Button}">                     <Filigree ten:Name="Chrome"                            Background="{TemplateBinding Background}"                            SnapsToDevicePixels="truthful"                           HorizontalAlignment="Stretch">                     <TextBlock                          Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"                         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"                                            Margin="{TemplateBinding Padding}"                                            Groundwork="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}"                                           SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"                         Fashion="{StaticResource MyTextBlockStyle}"/>                     </Filigree>                     <ControlTemplate.Triggers>                         <Trigger Property="IsMouseOver" Value="True">                             <Setter Property="Groundwork" Value="Black"/>                         </Trigger>                         <Trigger Property="Background" Value="White">                             <Setter Belongings="Foreground" Value="Aqua"/>                         </Trigger>                         <Trigger Property="Groundwork" Value="Transparent">                             <Setter Holding="Foreground" Value="BlueViolet"/>                         </Trigger>                         <Trigger Property="Groundwork" Value="Dark-green">                             <Setter Holding="Foreground" Value="Blue"/>                         </Trigger>                         <Trigger Property="Background" Value="Xanthous">                             <Setter Property="Foreground" Value="Red"/>                         </Trigger>                         <Trigger Belongings="Background" Value="Cherry">                             <Setter Belongings="Foreground" Value="Yellow"/>                         </Trigger>                         <Trigger Property="Groundwork" Value="Blackness">                             <Setter Property="Foreground" Value="DarkSeaGreen"/>                         </Trigger>                     </ControlTemplate.Triggers>                 </ControlTemplate>             </Setter.Value>         </Setter>          <Mode x:fundamental="MyTextBlockStyle" TargetType="TextBlock">     <Setter Property="FontSize" Value="12"/>     <Setter Property="FontStyle" Value="Italic"/>     <Manner.Triggers>         <Trigger Belongings="Background" Value="White">             <Setter Holding="Foreground" Value="Aqua"/>         </Trigger>         <Trigger Holding="Background" Value="Transparent">             <Setter Property="Foreground" Value="BlueViolet"/>         </Trigger>         <Trigger Holding="Background" Value="Green">             <Setter Property="Foreground" Value="Blueish"/>         </Trigger>         <Trigger Property="Background" Value="Yellow">             <Setter Property="Foreground" Value="Red"/>         </Trigger>         <Trigger Holding="Background" Value="Crimson">             <Setter Holding="Foreground" Value="Yellow"/>         </Trigger>         <Trigger Property="Groundwork" Value="Black">             <Setter Belongings="Foreground" Value="DarkSeaGreen"/>         </Trigger> </Style> </UserControl.Resources>

    When button is created in the XAML:

    <Push button Content="{Binding Name}" Style="{StaticResource NoChromeButton}"/>

    Besides, I would like to point out a couple of things in the above style:

    1. If I would take used ContentPresenter instead of TextBlock within the Grid named Chrome, background property was not assault the ContentPresenter and when I snooped the UI, I establish that the ContentPresenter has TextBlock whose Groundwork was e'er ready to Default and hence no styletriggers were applied to the TextBlock. Also, this TextBlock'due south groundwork valuesource is Default.

    On the other hand, when I use TextBlock directly inside the Grid named Chrome, I can fix its groundwork explicitly to Grid'due south Groundwork which is set to Button's Background. Snooping reveals that now TextBlock's Groundwork ValueSource is ParentTemplate.

    1. Button picks up MyTextBlockStyle while displaying its content.

    2. Style triggers for Button or TextBlock were never triggered unless I did mouse over the button which changes the push button's groundwork to Blackness and propagates this value down to TextBlock background changing the TextBlock's foreground color to DarkSeaGreen.

    3. Besides, changing the button's groundwork in snoop utility while application is running, triggers the Style Triggers.

    Questions:

    1. Why none of the Mode triggers work for Background property whereas they work for IsMouseOver property?

    2. What I am doing wrong?

    3. Whatever solution for this?

    Thanks,

    RDV

Answers

  • Hi

    Actually my reply is just concerning the subject area, how to adapt the foreground to the background,
    it's not exactely a detailed anwser to the question on your triggers and styles etc, sorry for that.

    Since in WPF there are 256 * 256 * 256 * 256 possible colors , => 2^32 => uint.Max
    createing an explicit trigger in xaml for each distinct possible color value likely exceeds the max file
    size the parser tin can read.

    I'd practise it with a converter or fastened holding and a default mode for the controls in question;
    and summate foreground based on the effulgence / luminosity of the background, according to this algoritm: Calculating the Perceived Brightness of a Colour

    The downside is that the foreground is but black or white, nil fancy

    looks like:

    auto-foreground.png

    Sample XAML

    <Window x:Class="AutoForeGround.MainWindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         xmlns:autoForeGround="clr-namespace:AutoForeGround"         Title="MainWindow"         Width="525"         Height="350">     <Window.Resources>         <Style TargetType="TextBlock">             <Setter Property="autoForeGround:AutoForeGroundExtension.AutoForeGround"                     Value="True" />             <Setter Property="Text">                 <Setter.Value>                     <MultiBinding StringFormat="{} {0} / {1}">                         <Binding RelativeSource="{RelativeSource Mode=Self}"                                  Path="(TextBlock.Foreground).(SolidColorBrush.Color)" />                         <Binding RelativeSource="{RelativeSource Mode=Self}"                                  Path="(TextBlock.Groundwork).(SolidColorBrush.Color)" />                     </MultiBinding>                 </Setter.Value>             </Setter>         </Style>     </Window.Resource>     <StackPanel>         <TextBlock Background="Black" />         <TextBlock Background="DarkRed" />         <TextBlock Groundwork="Cerise" />         <TextBlock Groundwork="Orange" />         <TextBlock Groundwork="Yellowish" />         <TextBlock Background="YellowGreen" />         <TextBlock Groundwork="Green" />         <TextBlock Background="LightCyan" />         <TextBlock Groundwork="Cyan" />         <TextBlock Background="DarkCyan" />         <TextBlock Groundwork="DarkBlue" />     </StackPanel> </Window>

    Attached belongings "AutoForeGroundExtension.AutoForeGround"

    using System; using Organisation.Windows; using Arrangement.Windows.Controls; using System.Windows.Documents; using Organisation.Windows.Media;  namespace AutoForeGround {     static class AutoForeGroundExtension     {         individual static readonly DependencyProperty[] _backGrounds = new [] { Control.BackgroundProperty, TextBlock.BackgroundProperty, Page.BackgroundProperty, TextElement.BackgroundProperty };         individual static readonly DependencyProperty[] _foreGrounds = new[] { Command.ForegroundProperty, TextBlock.ForegroundProperty, Page.ForegroundProperty, TextElement.ForegroundProperty };         private static readonly Type[] _ownerTypes = new[] { typeof(Control), typeof(TextBlock), typeof(Page), typeof(TextElement) };          public static readonly DependencyProperty AutoForeGroundProperty = DependencyProperty.RegisterAttached("AutoForeGround", typeof(bool), typeof(AutoForeGroundExtension), new PropertyMetadata(false, OnAutoForeGroundPropertyChangedCallback));         public static void SetAutoForeGround(DependencyObject element, bool value)         {             chemical element.SetValue(AutoForeGroundProperty, value);         }         public static bool GetAutoForeGround(DependencyObject element)         {             return (bool)element.GetValue(AutoForeGroundProperty);         }         private static void OnAutoForeGroundPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)         {              if (ReferenceEquals(d, nil))                 return;             if (!(eastward.NewValue is bool) || !(bool)e.NewValue)                 render;              for (int i = 0; i < _backGrounds.Length; i++)             {                 var dp = _backGrounds[i];                 var ownerType = _ownerTypes[i];                 if(!ownerType.IsInstanceOfType(d))                     continue;                  var brush = d.GetValue(dp) as SolidColorBrush;                 if(ReferenceEquals(brush, nothing))                     continue;                  var brightness = Brightness(brush.Color);                 var foreGround = brightness > 127 ? Brushes.Black : Brushes.White;                                  d.SetValue(_foreGrounds[i], foreGround);             }         }         private static int Effulgence(Color c)         {             return (int)Math.Sqrt(                c.R * c.R * .241 +                c.G * c.1000 * .691 +                c.B * c.B * .068);         }     } }

    goodbye
    Chris


    • Edited by Saturday, August 31, 2013 1:35 AM del typo, add image
    • Marked as answer past Franklin Chen Microsoft employee Mon, September 9, 2013 9:46 AM
  • In the style, you are binding the Background property of the Button to a property of its DataSource called Background. What'southward the value of this holding when the user window or user control loads? If the binding tin't be resolved, the button won't become any background until you move the mouse over it and the IsMouseOver trigger triggers, causing the background to change to blackness, which in plough causes the foreground to be inverse to DarkSeaGreen.

    In the following sample code, I use a view model with a Groundwork property that is initially set to light-green and this will crusade the push to be displayed with a green background and a blue foreground, equally the style specifies:

    form ViewModel     {         public ViewModel()         {             this.Background = "Green";         }          public string Background { become; set; }     }                    

    public partial class MainWindow : Window     {         public MainWindow()         {             InitializeComponent();             this.DataContext = new ViewModel();  }     }

    <Window x:Class="WpfApplication1.MainWindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:ten="http://schemas.microsoft.com/winfx/2006/xaml"         Title="MainWindow" Top="350" Width="525">     <Window.Resources>         <Style 10:Key="MyTextBlockStyle" TargetType="TextBlock">             <Setter Holding="FontSize" Value="12"/>             <Setter Property="FontStyle" Value="Italic"/>             <Style.Triggers>                 <Trigger Property="Background" Value="White">                     <Setter Belongings="Foreground" Value="Aqua"/>                 </Trigger>                 <Trigger Property="Groundwork" Value="Transparent">                     <Setter Belongings="Foreground" Value="BlueViolet"/>                 </Trigger>                 <Trigger Property="Background" Value="Green">                     <Setter Property="Foreground" Value="Blueish"/>                 </Trigger>                 <Trigger Holding="Background" Value="Yellowish">                     <Setter Property="Foreground" Value="Red"/>                 </Trigger>                 <Trigger Property="Groundwork" Value="Cherry">                     <Setter Belongings="Foreground" Value="Yellow"/>                 </Trigger>                 <Trigger Property="Groundwork" Value="Black">                     <Setter Property="Foreground" Value="DarkSeaGreen"/>                 </Trigger>             </Style.Triggers>         </Style>         <Style ten:Key="NoChromeButton" TargetType="{x:Type Button}">             <Setter Property="Background" Value="{Bounden Background}"/>             <Setter Belongings="OverridesDefaultStyle" Value="True"/>             <Setter Property="BorderThickness" Value="1"/>             <Setter Property="BorderBrush" Value="White"/>             <Setter Property="HorizontalContentAlignment" Value="Eye"/>             <Setter Belongings="VerticalContentAlignment" Value="Eye"/>             <Setter Property="Padding" Value="i"/>             <Setter Property="Template">                 <Setter.Value>                     <ControlTemplate TargetType="{x:Type Button}">                         <Grid ten:Name="Chrome"                            Groundwork="{TemplateBinding Background}"                            SnapsToDevicePixels="truthful"                           HorizontalAlignment="Stretch">                             <TextBlock                          Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"                         HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"                                            Margin="{TemplateBinding Padding}"                                            Background="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}"                                           SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"                                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"                         Style="{StaticResource MyTextBlockStyle}"/>                         </Grid>                         <ControlTemplate.Triggers>                             <Trigger Belongings="IsMouseOver" Value="True">                                 <Setter Property="Background" Value="Black"/>                             </Trigger>                             <Trigger Holding="Groundwork" Value="White">                                 <Setter Holding="Foreground" Value="Aqua"/>                             </Trigger>                             <Trigger Property="Background" Value="Transparent">                                 <Setter Property="Foreground" Value="BlueViolet"/>                             </Trigger>                             <Trigger Holding="Background" Value="Dark-green">                                 <Setter Property="Foreground" Value="Blue"/>                             </Trigger>                             <Trigger Holding="Background" Value="Yellow">                                 <Setter Property="Foreground" Value="Blood-red"/>                             </Trigger>                             <Trigger Holding="Background" Value="Ruby">                                 <Setter Holding="Foreground" Value="Xanthous"/>                             </Trigger>                             <Trigger Holding="Groundwork" Value="Black">                                 <Setter Holding="Foreground" Value="DarkSeaGreen"/>                             </Trigger>                         </ControlTemplate.Triggers>                     </ControlTemplate>                 </Setter.Value>             </Setter>         </Style>     </Window.Resources>     <StackPanel>         <Button Content="Name" Style="{StaticResource NoChromeButton}"/>     </StackPanel> </Window>

    If you change the value of the Background belongings in the view model at runtime and want the change to be reflected in the view, the view model should implement the INotifyPropertyChanged:

    class ViewModel : INotifyPropertyChanged     {         public ViewModel()         {             this.Background = "Green";         }          private string _bg;         public string Background         {             go { return _bg; }             set { _bg = value; NotifyPropertyChanged("Groundwork"); }         }          public consequence PropertyChangedEventHandler PropertyChanged;         private void NotifyPropertyChanged(string propertyName)         {             if (PropertyChanged != null)                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));         }     }                    

    • Marked as respond by Franklin Chen Microsoft employee Mon, September ix, 2013 9:46 AM

Source: https://social.msdn.microsoft.com/Forums/en-US/3c96bce1-5b2c-4bb2-81a8-d3fb87a7beaa/change-foreground-color-dynamically-based-on-background-color

Posted by: sowellholed1992.blogspot.com

0 Response to "How To Change Foreground And Background In Html When You Move Mouse Over It"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel