WPF: Add a dropshadow effect to an element from code-behind - c#

I thought this would be something simple but so far i found nothing. How do you do it?

The accepted answer is now obsolete. Now you may use:
UIElement uie = ...
uie.Effect =
new DropShadowEffect
{
Color = new Color {A = 255, R = 255, G = 255, B = 0},
Direction = 320,
ShadowDepth = 0,
Opacity = 1
};
To achieve the exact same effect as the accepted answer.

just try this
// Get a reference to the Button.
Button myButton = new Button();
// Initialize a new DropShadowBitmapEffect that will be applied
// to the Button.
DropShadowBitmapEffect myDropShadowEffect = new DropShadowBitmapEffect();
// Set the color of the shadow to Black.
Color myShadowColor = new Color();
myShadowColor.ScA = 1;
myShadowColor.ScB = 0;
myShadowColor.ScG = 0;
myShadowColor.ScR = 0;
myDropShadowEffect.Color = myShadowColor;
// Set the direction of where the shadow is cast to 320 degrees.
myDropShadowEffect.Direction = 320;
// Set the depth of the shadow being cast.
myDropShadowEffect.ShadowDepth = 25;
// Set the shadow softness to the maximum (range of 0-1).
myDropShadowEffect.Softness = 1;
// Set the shadow opacity to half opaque or in other words - half transparent.
// The range is 0-1.
myDropShadowEffect.Opacity = 0.5;
// Apply the bitmap effect to the Button.
myButton.BitmapEffect = myDropShadowEffect;

#Gleno's answer helped me the most. In my case I was using it for visual feedback on a missed form item. To then remove the dropshadow I used:
myComboBox.ClearValue(EffectProperty);
in a selectionChanged event.
Hope this helps someone. I had to search for a bit.

Related

Setting fixed major grid marks independent of data range

This is my first project in c# and I'm trying to create plots from data.
I'm struggling with drawing minor and major grid lines and labels on a logarithmic scale.
I've set the scale to logarithmic, set the base to 10 and both major and minor intervals to 1, and it works great, however, the interval starts with the minimum value on scale, so for example if data starts at 30M (I'm dealing with frequencies) the next major tick is at 300M and 3G, which is not as it should be.
Is there a way to set major grid to 1, 10, 100 etc, independent of what data is displayed? i've tried changing intervals, base and offset but have not achieved much.
area.AxisX.IsLogarithmic = true;
area.AxisX.LogarithmBase = 10;
area.AxisX.Interval = 1;
//area.AxisX.IntervalOffset = 10000;
area.AxisX.IntervalAutoMode = IntervalAutoMode.FixedCount;
area.AxisX.MajorGrid.Enabled = true;
area.AxisX.MajorTickMark.Enabled = true;
area.AxisX.MinorGrid.Enabled = true;
area.AxisX.MinorGrid.Interval = 1;
area.AxisX.MinorTickMark.Enabled = true;
area.AxisX.MinorTickMark.Interval = 1;
area.AxisX.Minimum = minMaxXY[0]; // in this example 30 M
area.AxisX.Maximum = minMaxXY[1]; // in this example 1 G
here's the link to the current grid
https://ibb.co/3WkxLfc
Thank you for your time and answers!
Thanks to TaW replay I managed to get my program working.
Here is my solution using customLabels location to draw the grid lines.
private void Chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
if (e.Chart.ChartAreas.Count > 0) // I don't yet truly understand when this event occurs,
// so I got plenty of null references.
{
Graphics g = e.ChartGraphics.Graphics;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
Color minorGridColor = Color.Gainsboro;
ChartArea area = e.Chart.ChartAreas[0];
double aymin = area.AxisY.Minimum;
double aymax = area.AxisY.Maximum;
int y0 = (int)area.AxisY.ValueToPixelPosition(aymin);
int y1 = (int)area.AxisY.ValueToPixelPosition(aymax);
foreach (var label in chart1.ChartAreas[0].AxisX.CustomLabels)
{
double xposition = area.AxisX.ValueToPixelPosition(Math.Pow(10, label.FromPosition + 0.1));
if (xposition > area.AxisX.ValueToPixelPosition(minMaxXY[0]) && xposition < area.AxisX.ValueToPixelPosition(minMaxXY[1]))
//this prevents drawing of lines outside of the chart area
{
int x = (int)xposition;
using (Pen dashed_pen = new Pen(Color.FromArgb(10, 0, 0, 0), 1))
{
dashed_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
g.DrawLine(dashed_pen, x, y0, x, y1);
}
}
}
}
}
I also found the CustomLabel.GridTicks Property, but for some reason it did not work.

C# Unable to dynamicly auto-size columns evenly in TableLayoutPanel

I have a WinForm that has a TableLayoutPanel control. My code will detect the number of attached monitors on screen, create a column per monitor, and then add a button for each display within each individual column in the TableLayoutControl so I can ensure that no matter how many monitors are attached, the buttons will appear "centered" across the form. One/two monitors renders just fine, however three monitors results in end columns not being evenly distributed.
Here is my code:
int count = Screen.AllScreens.Count();
this.monitorLayoutPanel.ColumnCount = count;
ColumnStyle cs = new ColumnStyle(SizeType.Percent, 100 / count);
this.monitorLayoutPanel.ColumnStyles.Add(cs);
this.monitorLayoutPanel.AutoSize = true;
var buttonSize = new Size(95, 75);
int z = 0;
foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
{
Button monitor = new Button
{
Name = "Monitor" + screen,
AutoSize = true,
Size = buttonSize,
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
Anchor = System.Windows.Forms.AnchorStyles.None
};
this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
z++;
monitor.MouseClick += new MouseEventHandler(monitor_Click);
}
I've tried making the buttons smaller, and increased the form size but the last column is always smaller than the first two. I can't understand it!
Clear ColumnStyles first.
this.monitorLayoutPanel.ColumnStyles.Clear();
then:
int count = Screen.AllScreens.Count();
for (int i = 0; i < count; i++)
{
ColumnStyle cs = new ColumnStyle(SizeType.Percent, (float)100 / count);
this.monitorLayoutPanel.ColumnStyles.Add(cs);
}
this.monitorLayoutPanel.AutoSize = true;
...
Reza Aghaei pointed me to this thread How to create a magic square using Windows Forms? which pointed me in the right direction. Updated (and working) code below. :)
int screens = Screen.AllScreens.Count();
this.monitorLayoutPanel.ColumnStyles.Clear();
this.monitorLayoutPanel.ColumnCount = screens;
this.monitorLayoutPanel.AutoSize = true;
int z = 0;
foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
{
var percent = 100f / screens;
this.monitorLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, percent));
Button monitor = new Button
{
Name = "Monitor" + screen,
Size = new Size(95, 75),
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
Anchor = System.Windows.Forms.AnchorStyles.None
};
this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
z++;
monitor.MouseClick += new MouseEventHandler(monitor_Click);

Asp.net chart, how can I set the X axis label position to left aligned instead of centered?

I've spent hours trying to solve this silly problem. I create an histogram with asp chart control. All I want to do is have the xaxis label on the left of the column instead of centered on it. Xaxis lable doesn't seem to have a position property like series do, so I can't figure it out and it's frustrating.
Here's a sample code of the type of graphic I'm talking about to show you what I get approximately:
private void Graphique()
{
// Creating the series
Series series2 = new Series("Series2");
// Setting the Chart Types
series2.ChartType = SeriesChartType.Column;
// Adding some points
series2.Points.AddXY(1492, 12);
series2.Points.AddXY(2984, 0);
series2.Points.AddXY(4476, 1);
series2.Points.AddXY(5968, 2);
series2.Points.AddXY(7460, 2);
series2.Points.AddXY(8952, 12);
series2.Points.AddXY(10444, 4);
series2.Points.AddXY(11936, 3);
series2.Points.AddXY(13428, 3);
series2.Points.AddXY(14920, 5);
series2.Points.AddXY(16412, 1);
Chart3.Series.Add(series2);
Chart3.Width = 600;
Chart3.Height = 600;
// Series visual
series2.YValueMembers = "Frequency";
series2.XValueMember = "RoundedValue";
series2.BorderWidth = 1;
series2.ShadowOffset = 0;
series2.IsXValueIndexed = true;
// Setting the X Axis
Chart3.ChartAreas["ChartArea1"].AxisX.IsMarginVisible = true;
Chart3.ChartAreas["ChartArea1"].AxisX.Interval = 1;
Chart3.ChartAreas["ChartArea1"].AxisX.Maximum = Double.NaN;
Chart3.ChartAreas["ChartArea1"].AxisX.Title = "kbps";
// Setting the Y Axis
Chart3.ChartAreas["ChartArea1"].AxisY.Interval = 2;
Chart3.ChartAreas["ChartArea1"].AxisY.Maximum = Double.NaN;
Chart3.ChartAreas["ChartArea1"].AxisY.Title = "Frequency";
}
Now my real chart looks like this, Actual result
I would like something similar to this website :
Desired layout chart
You see, the x label is on the left, which makes way more sense considering that each column of an histogram represents the frequency of a range of values.....
Any help would be appreciated...
Did you try to add CustomLabels to replace the default ones? For example:
for (int i = 0; i <= 10; i++) {
area.AxisX.CustomLabels.Add(i + 0.5, i + 1.5, i, 0, LabelMarkStyle.None);
}
The first two are for positioning and the third would be the text value of the label.

MS Chart, add triangles to an existing chart at specific points

Im wondering if its possible to add colored triangles (pointing up or down) at specific points (x,y) on an existing chart, such that they will update their positions if the chart is scrolled/zoomed.
Ive had a google around but havent stumbled across anything which seems to meet those requirements.
Any pointers would be appreciated.
Draw a point chart with markers.
Create your own image and use MarkerImage property to load custom image
Answer Explaining how to get your inverted triangles
Custom MarkerStyles possible in Microsoft Chart Controls?
As described inside the MS Chart Samples, you could probably use annotations for this
private void AddLineAnnotation()
{
LineAnnotation annotation = new LineAnnotation();
annotation.AnchorDataPoint = Chart1.Series[0].Points[2];
annotation.Height = -25;
annotation.Width = -25;
annotation.LineWidth = 2;
annotation.StartCap = LineAnchorCapStyle.Arrow;
annotation.EndCap = LineAnchorCapStyle.Arrow;
Chart1.Annotations.Add(annotation);
}
You can even define a custom polygon as annotation
private void AddPolygonAnnotation()
{
PolygonAnnotation annotation = new PolygonAnnotation();
annotation.AnchorDataPoint = Chart1.Series[0].Points[2];
// explicitly set the relative height and width
annotation.Height = 50;
annotation.Width = 30;
annotation.BackColor = Color.FromArgb(128, Color.Orange);
annotation.LineColor = Color.Black;
annotation.LineDashStyle = ChartDashStyle.Solid;
// define relative value points for a polygon
PointF [] points = new PointF[5];
points[0].X = 0;
points[0].Y = 0;
points[1].X = 100;
points[1].Y = 0;
points[2].X = 100;
points[2].Y = 100;
points[3].X = 0;
points[3].Y = 100;
points[4].X = 50;
points[4].Y = 50;
annotation.Path.AddPolygon(points);
Chart1.Annotations.Add(annotation);
}

How to animate opacity of dropshadoweffect in C# code?

How do I go about animating the opacity of a dropshadoweffect in code. I am dynamically creating stackpanels in my UI which contain an image and a text block. I have applied a dropshadoweffect to the image, which I would like to animate the opacity. Here's what I have:
Image img = ch.ChannelLogo; //Create the image for the button
img.Height = channelStackPnl.Height * .66;
DropShadowEffect dSE = new DropShadowEffect();
dSE.Color = Colors.White;
dSE.Direction = 25;
dSE.ShadowDepth = 10;
dSE.Opacity = .40;
img.Effect = dSE;
DoubleAnimation animateOpacity = new DoubleAnimation();
animateOpacity.From = 0;
animateOpacity.To = 1;
animateOpacity.AutoReverse = true;
animateOpacity.RepeatBehavior = RepeatBehavior.Forever;
animateOpacity.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 400));
//Here's where I am stuck. How do I specifically target the opacity of the effect propery?
img.BeginAnimationimg.BeginAnimation(DropShadowEffect.OpacityProperty,animateOpacity);
dSE.BeginAnimation(DropShadowEffect.OpacityProperty, animateOpacity);
Probably...
(You are animating the effect, not the image)

Categories