问题
I am developing wpf application. I am having the instance of Color object in C#. Suppose I have instance of red Color object i.e. Color c = Color.FromArgb(255,255,0,0)
Now suppose that I have one value which ranges from 1 to 10. So based on this value I want to change the color of the 'c' object. I want light red for 1 and dark red for 10. The light red becomes the dark as the value increases from 1. How can I do this in C# for wpf application ? Can you please provide me any code or link through which I can resolve the above issue ?
回答1:
You can try to simply multiply red, green and blue components by some coefficient.
public static Color ChangeLightness(this Color color, float coef)
{
return Color.FromArgb((int)(color.R * coef), (int)(color.G * coef),
(int)(color.B * coef));
}
Or, if you'd like to use an integer value from 1 to 10 instead of the coefficient:
private const int MinLightness = 1;
private const int MaxLightness = 10;
private const float MinLightnessCoef = 1f;
private const float MaxLightnessCoef = 0.4f;
public static Color ChangeLightness(this Color color, int lightness)
{
if (lightness < MinLightness)
lightness = MinLightness;
else if (lightness > MaxLightness)
lightness = MaxLightness;
float coef = MinLightnessCoef +
(
(lightness - MinLightness) *
((MaxLightnessCoef - MinLightnessCoef) / (MaxLightness - MinLightness))
);
return Color.FromArgb(color.A, (int)(color.R * coef), (int)(color.G * coef),
(int)(color.B * coef));
}
回答2:
Let's say you're using a slider with a minimum value of 1
and a maximum value of 10
. You can just multiply the value by 25.5 (255 / max value)
. Then, subtract that answer from max value (255) and use that as the red value.
double newRedValue = 255 - (slider.Value * (255 / slider.Maximum));
int redValue = Convert.ToInt32(newRedValue);
Color c = Color.FromArgb(redValue ,255,0,0)
You can replace 255 / slider.Maximum
with a constant value since it will likely remain the same. The formula above will create an inverse effect, so the lower the slider value, the brighter the shade of red. Of course, a value of 10 will result in red
being 0
, so you can add a minimum there value if you don't want the red component to be that low.
回答3:
What about a Style DataTrigger, if you have a set number of values?
https://www.google.co.uk/search?q=c%23+wpf+style+datatrigger
<Button>
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding NameOfYourProperty}" Value="0">
<Setter Property="Background"
Value="#FF000000" />
</DataTrigger>
<DataTrigger Binding="{Binding NameOfYourProperty}" Value="1">
<Setter Property="Background"
Value="#FF110000" />
</DataTrigger>
<DataTrigger Binding="{Binding NameOfYourProperty}" Value="2">
<Setter Property="Background"
Value="#FF220000" />
</DataTrigger>
( etc ... )
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Then if you need to reuse the style then you could put in the <Resources>
section of your window/usercontrol.
回答4:
A cleaner solution would be to juxtapose 2 rectangles: one is the color you want, the other is black.
Then play with Opacity
on the black rectangle to darken/lighten the underlying color.
It would look like:
<Grid>
<Rectangle Fill="{Binding myColor}" />
<Rectangle Fill="Black" Opacity="{Binding colorModifierPercentage}" />
</Grid>
Of course, colorModifierPercentage
must be a number between 0 and 1, and rectangle can be any Shape.
回答5:
There is an article about it at CodeProject:
/// <summary>
/// Converts a WPF RGB color to an HSL color
/// </summary>
/// <param name="rgbColor">The RGB color to convert.</param>
/// <returns>An HSL color object equivalent to the RGB color object passed in.</returns>
static HlsColor RgbToHls(Color rgbColor)
{
// Initialize result
var hlsColor = new HlsColor();
// Convert RGB values to percentages
double r = (double)rgbColor.R / 255;
var g = (double)rgbColor.G / 255;
var b = (double)rgbColor.B / 255;
var a = (double)rgbColor.A / 255;
// Find min and max RGB values
var min = Math.Min(r, Math.Min(g, b));
var max = Math.Max(r, Math.Max(g, b));
var delta = max - min;
/* If max and min are equal, that means we are dealing with
* a shade of gray. So we set H and S to zero, and L to either
* max or min (it doesn't matter which), and then we exit. */
//Special case: Gray
if (max == min)
{
hlsColor.H = 0;
hlsColor.S = 0;
hlsColor.L = max;
return hlsColor;
}
/* If we get to this point, we know we don't have a shade of gray. */
// Set L
hlsColor.L = (min + max) / 2;
// Set S
if(hlsColor.L < 0.5)
{
hlsColor.S = delta / (max + min);
}
else
{
hlsColor.S = delta / (2.0 - max - min);
}
// Set H
if (r == max) hlsColor.H = (g - b) / delta;
if (g == max) hlsColor.H = 2.0 + (b - r) / delta;
if (b == max) hlsColor.H = 4.0 + (r - g) / delta;
hlsColor.H *= 60;
if (hlsColor.H < 0) hlsColor.H += 360;
// Set A
hlsColor.A = a;
// Set return value
return hlsColor;
}
/// <summary>
/// Converts a WPF HSL color to an RGB color
/// </summary>
/// <param name="hlsColor">The HSL color to convert.</param>
/// <returns>An RGB color object equivalent to the HSL color object passed in.</returns>
static Color HlsToRgb(HlsColor hlsColor)
{
// Initialize result
var rgbColor = new Color();
/* If S = 0, that means we are dealing with a shade
* of gray. So, we set R, G, and B to L and exit. */
// Special case: Gray
if (hlsColor.S == 0)
{
rgbColor.R = (byte)(hlsColor.L * 255);
rgbColor.G = (byte)(hlsColor.L * 255);
rgbColor.B = (byte)(hlsColor.L * 255);
rgbColor.A = (byte)(hlsColor.A * 255);
return rgbColor;
}
double t1;
if (hlsColor.L < 0.5)
{
t1 = hlsColor.L*(1.0 + hlsColor.S);
}
else
{
t1 = hlsColor.L + hlsColor.S - (hlsColor.L * hlsColor.S);
}
var t2 = 2.0*hlsColor.L - t1;
// Convert H from degrees to a percentage
var h = hlsColor.H / 360;
// Set colors as percentage values
var tR = h + (1.0/3.0);
var r = SetColor(t1, t2, tR);
var tG = h;
var g = SetColor(t1, t2, tG);
var tB = h - (1.0 / 3.0);
var b = SetColor(t1, t2, tB);
// Assign colors to Color object
rgbColor.R = (byte)(r * 255);
rgbColor.G = (byte)(g * 255);
rgbColor.B = (byte)(b * 255);
rgbColor.A = (byte)(hlsColor.A * 255);
// Set return value
return rgbColor;
}
/// <summary>
/// Used by the HSL-to-RGB converter.
/// </summary>
/// <param name="t1">A temporary variable.</param>
/// <param name="t2">A temporary variable.</param>
/// <param name="t3">A temporary variable.</param>
/// <returns>An RGB color value, in decimal format.</returns>
private static double SetColor(double t1, double t2, double t3)
{
if (t3 < 0) t3 += 1.0;
if (t3 > 1) t3 -= 1.0;
double color;
if (6.0 * t3 < 1)
{
color = t2 + (t1 - t2) * 6.0 * t3;
}
else if(2.0 * t3 < 1)
{
color = t1;
}
else if(3.0*t3 < 2)
{
color = t2 + (t1 - t2) * ((2.0/3.0) - t3) * 6.0;
}
else
{
color = t2;
}
// Set return value
return color;
}
来源:https://stackoverflow.com/questions/12894605/how-to-make-specific-color-darken-or-lighten-based-on-value-in-wpf