MediaElement freezes video - c#

I apply some LinearGradientBrush animation to MediaElement and after this video is freezing.
I try to reset it via Player1.OpacityMask = null; but no joy.
By the way if I animate Opacity of the MediaElement then video shows good as usually.
Any clue what's up? How to fix the video freezing after applying LinearGradientBrush animation to MediaElement ?
Thank you!
/// <summary>
/// Interaction logic for WipeTransition.xaml
/// </summary>
public partial class WipeTransition
{
public WipeDirections Direction { set; get; }
public TimeSpan Duration = TimeSpan.FromSeconds(2);
public bool StopPrevPlayerOnAnimationStarts;
Random rdm = new Random(1);
bool isPlayer1;
public WipeTransition()
{
InitializeComponent();
try
{
Loaded += WipeTransition_Loaded;
SizeChanged += WipeTransition_SizeChanged;
Player1.CacheMode = new BitmapCache();
Player1.LoadedBehavior = MediaState.Manual;
Player2.CacheMode = new BitmapCache();
Player2.LoadedBehavior = MediaState.Manual;
Direction = WipeDirections.RandomDirection;
Player1.Width = ActualWidth;
Player2.Width = ActualWidth;
Player1.Height = ActualHeight;
Player2.Height = ActualHeight;
isPlayer1 = true;
}
catch (Exception)
{
}
}
void WipeTransition_SizeChanged(object sender, SizeChangedEventArgs e)
{
Player1.Width = ActualWidth;
Player2.Width = ActualWidth;
Player1.Height = ActualHeight;
Player2.Height = ActualHeight;
}
void WipeTransition_Loaded(object sender, RoutedEventArgs e)
{
Player1.Width = ActualWidth;
Player2.Width = ActualWidth;
Player1.Height = ActualHeight;
Player2.Height = ActualHeight;
}
public void Start(Uri uri)
{
try
{
Debug.WriteLine("************** START ANIMATION ***************************************");
Player1.Width = ActualWidth;
Player2.Width = ActualWidth;
Player1.Height = ActualHeight;
Player2.Height = ActualHeight;
// We start to Animate one of the Player is on BACK
if (isPlayer1)
{
if (StopPrevPlayerOnAnimationStarts)
Player2.Stop();
Canvas.SetZIndex(Player2, 49);
Canvas.SetZIndex(Player1, 50);
Player1.Source = uri;
Debug.WriteLine("Player1 - ANIMATE");
WipeAnimation(Player1);
}
else // Player2
{
if (StopPrevPlayerOnAnimationStarts)
Player1.Stop();
Canvas.SetZIndex(Player1, 49);
Canvas.SetZIndex(Player2, 50);
Player2.Source = uri;
Debug.WriteLine("Player2 - ANIMATE");
WipeAnimation(Player2);
}
}
catch (Exception)
{
}
}
public void WipeAnimation(FrameworkElement ObjectToAnimate)
{
try
{
LinearGradientBrush OpacityBrush = new LinearGradientBrush();
#region Setup Wipe Direction
switch (Direction)
{
case WipeDirections.RightToLeft:
OpacityBrush.StartPoint = new Point(1, 0);
OpacityBrush.EndPoint = new Point(0, 0);
break;
case WipeDirections.LeftToRight:
OpacityBrush.StartPoint = new Point(0, 0);
OpacityBrush.EndPoint = new Point(1, 0);
break;
case WipeDirections.BottomToTop:
OpacityBrush.StartPoint = new Point(0, 1);
OpacityBrush.EndPoint = new Point(0, 0);
break;
case WipeDirections.TopToBottom:
OpacityBrush.StartPoint = new Point(0, 0);
OpacityBrush.EndPoint = new Point(0, 1);
break;
case WipeDirections.RandomDirection:
#region
int randomValue = rdm.Next(0, 3);
if (randomValue == 0)
{
OpacityBrush.StartPoint = new Point(1, 0);
OpacityBrush.EndPoint = new Point(0, 0);
}
else if (randomValue == 1)
{
OpacityBrush.StartPoint = new Point(0, 0);
OpacityBrush.EndPoint = new Point(0, 1);
}
else if (randomValue == 2)
{
OpacityBrush.StartPoint = new Point(0, 0);
OpacityBrush.EndPoint = new Point(1, 0);
}
else if (randomValue == 3)
{
OpacityBrush.StartPoint = new Point(0, 1);
OpacityBrush.EndPoint = new Point(0, 0);
}
#endregion
break;
}
#endregion
GradientStop BlackStop = new GradientStop(Colors.Black, 0);
GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
if (FindName("TransparentStop") != null)
UnregisterName("TransparentStop");
RegisterName("TransparentStop", TransparentStop);
if (FindName("BlackStop") != null)
UnregisterName("BlackStop");
this.RegisterName("BlackStop", BlackStop);
OpacityBrush.GradientStops.Add(BlackStop);
OpacityBrush.GradientStops.Add(TransparentStop);
ObjectToAnimate.OpacityMask = OpacityBrush;
Storyboard sb = new Storyboard();
DoubleAnimation DA = new DoubleAnimation() { From = 0, To = 1, Duration = Duration };
DoubleAnimation DA2 = new DoubleAnimation() { From = 0, To = 1, Duration = Duration };
sb.Children.Add(DA); sb.Children.Add(DA2);
Storyboard.SetTargetName(DA, "TransparentStop");
Storyboard.SetTargetName(DA2, "BlackStop");
Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
sb.Duration = Duration;
sb.Completed += sb_Completed;
sb.Begin(this);
if (isPlayer1)
{
Player1.Play();
}
else // Player2
{
Player2.Play();
}
}
catch (Exception)
{
}
}
void sb_Completed(object sender, EventArgs e)
{
if (isPlayer1)
{
Player1.OpacityMask = null;
isPlayer1 = false;
Player2.Stop();
Player2.Source = null;
}
else // Player2
{
Player2.OpacityMask = null;
isPlayer1 = true;
Player1.Stop();
Player1.Source = null;
}
Debug.WriteLine("************** END ANIMATION ***************************************");
}
public void Stop()
{
if (Player1.IsEnabled)
Player1.Stop();
if (Player2.IsEnabled)
Player2.Stop();
}
}
UPDATE:
The same problem happens after I apply shader effect. So video goes well before it and after this it is jumping/freezing. It seems that we have somehow to reset MedieElement or?
private void Button_Click_1(object sender, RoutedEventArgs e)
{
TransitionEffect[] effectGroup = transitionEffects[1];
TransitionEffect effect = effectGroup[1];
DoubleAnimation da = new DoubleAnimation(0.0, 1.0, new Duration(TimeSpan.FromSeconds(2.0)), FillBehavior.HoldEnd);
da.AccelerationRatio = 0.5;
da.DecelerationRatio = 0.5;
da.Completed += da_Completed;
effect.BeginAnimation(TransitionEffect.ProgressProperty, da);
VisualBrush vb = new VisualBrush(this.Player1);
vb.Viewbox = new Rect(0, 0, this.Player1.ActualWidth, this.Player1.ActualHeight);
vb.ViewboxUnits = BrushMappingMode.Absolute;
effect.OldImage = vb;
this.Player1.Effect = effect;
}

Related

How to update countdown timers in a DataGridView?

I created a DataGridView (Building queue) which can be filled by the user. The user has to insert the time [Textbox H and M] it has to wait. After selecting the buildings and adding them to the queue, the user can press start [Button Start/Stop] and the countdown still start for a maximum of 4 buildings at a time [Textbox named Builders].
Added buildings to the queue:
Pressed Start. 4 countdowns running. 5th one is waiting.
After the first timer hits zero, the row of that timer will be deleted. The program isn't using the right timers. (There was a bit of delay between the screenshots.) The first row has been duplicated. The first row timer has stopped working. and the others are still counting down. But the 5th row, disappeared.
I want the program to be able to continue with the next building countdown whenever one of the four countdowns is finished.
public void TimerFirstRow_Tick(object sender, EventArgs e)
{
if (time0 > 0 && this.dataGridView1.Rows.Count > 0)
{
time0--;
this.dataGridView1.Rows[0].Cells[2].Value = string.Format("00:{0}:{1}", time0 / 60, time0 % 60);
}
else
{
timer_0.Stop();
}
And I think here is the mistake / error, the place of the countdown is hardcoded into the Timer Tick event code.
The start button code:
private void StartButton_Click(object sender, EventArgs e)
{
QueueMax = this.dataGridView1.Rows.Count;
if (MaxBuild.Text == "")
{
label3.Text = "Fill MaxBuilders:";
}
else
{
MaxBuilder = int.Parse(MaxBuild.Text);
}
if (QueueMax >= MaxBuilder)
{
if (!timerB)
{
if (QueueMax > 0)
{
if (QueueMax == 1)
{
string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
string[] xyList = xycoord.Split(':');
int x = int.Parse(xyList[0]);
int y = int.Parse(xyList[1]);
this.WindowState = FormWindowState.Minimized;
Thread.Sleep(500);
SendKeys.Send("%+{TAB}");
Klikken(x, y);
this.WindowState = FormWindowState.Normal;
time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
timer_0 = new DispatcherTimer();
timer_0.Interval = new TimeSpan(0, 0, 1);
timer_0.Tick += TimerFirstRow_Tick;
timer_0.Start();
StartButton.Text = "Stop";
timerB = true;
}
else if (QueueMax == 2)
{
string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
string[] xyList = xycoord.Split(':');
int x = int.Parse(xyList[0]);
int y = int.Parse(xyList[1]);
this.WindowState = FormWindowState.Minimized;
Thread.Sleep(500);
SendKeys.Send("%+{TAB}");
Klikken(x, y);
string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
string[] xyList1 = xycoord.Split(':');
int x1 = int.Parse(xyList[0]);
int y1 = int.Parse(xyList[1]);
Klikken(x1, y1);
this.WindowState = FormWindowState.Normal;
time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
timer_0 = new DispatcherTimer();
timer_1 = new DispatcherTimer();
timer_0.Interval = new TimeSpan(0, 0, 1);
timer_1.Interval = new TimeSpan(0, 0, 1);
timer_0.Tick += TimerFirstRow_Tick;
timer_1.Tick += timer2_Tick_1;
timer_0.Start();
timer_1.Start();
StartButton.Text = "Stop";
timerB = false;
}
else if (QueueMax == 3)
{
string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
string[] xyList = xycoord.Split(':');
int x = int.Parse(xyList[0]);
int y = int.Parse(xyList[1]);
this.WindowState = FormWindowState.Minimized;
Thread.Sleep(500);
SendKeys.Send("%+{TAB}");
Klikken(x, y);
string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
string[] xyList1 = xycoord.Split(':');
int x1 = int.Parse(xyList[0]);
int y1 = int.Parse(xyList[1]);
Klikken(x1, y1);
string xycoord2 = this.dataGridView1.Rows[2].Cells[3].Value.ToString();
string[] xyList2 = xycoord.Split(':');
int x2 = int.Parse(xyList[0]);
int y2 = int.Parse(xyList[1]);
Klikken(x1, y1);
this.WindowState = FormWindowState.Normal;
time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
time2 = Convert.ToInt32(this.dataGridView1.Rows[2].Cells[2].Value) * 60;
timer_0 = new DispatcherTimer();
timer_1 = new DispatcherTimer();
timer_2 = new DispatcherTimer();
timer_0.Interval = new TimeSpan(0, 0, 1);
timer_1.Interval = new TimeSpan(0, 0, 1);
timer_2.Interval = new TimeSpan(0, 0, 1);
timer_0.Tick += TimerFirstRow_Tick;
timer_1.Tick += timer2_Tick_1;
timer_2.Tick += timer3_Tick;
timer_0.Start();
timer_1.Start();
timer_2.Start();
StartButton.Text = "Stop";
timerB = false;
}
else if (QueueMax >= 4)
{
string xycoord = this.dataGridView1.Rows[0].Cells[3].Value.ToString();
string[] xyList = xycoord.Split(':');
int x = int.Parse(xyList[0]);
int y = int.Parse(xyList[1]);
this.WindowState = FormWindowState.Minimized;
Klikken(x, y);
string xycoord1 = this.dataGridView1.Rows[1].Cells[3].Value.ToString();
string[] xyList1 = xycoord.Split(':');
int x1 = int.Parse(xyList[0]);
int y1 = int.Parse(xyList[1]);
Thread.Sleep(500);
SendKeys.Send("%+{TAB}");
Klikken(x1, y1);
string xycoord2 = this.dataGridView1.Rows[2].Cells[3].Value.ToString();
string[] xyList2 = xycoord.Split(':');
int x2 = int.Parse(xyList[0]);
int y2 = int.Parse(xyList[1]);
Klikken(x1, y1);
string xycoord3 = this.dataGridView1.Rows[3].Cells[3].Value.ToString();
string[] xyList3 = xycoord.Split(':');
int x3 = int.Parse(xyList[0]);
int y3 = int.Parse(xyList[1]);
Klikken(x1, y1);
this.WindowState = FormWindowState.Normal;
time0 = Convert.ToInt32(this.dataGridView1.Rows[0].Cells[2].Value) * 60;
time1 = Convert.ToInt32(this.dataGridView1.Rows[1].Cells[2].Value) * 60;
time2 = Convert.ToInt32(this.dataGridView1.Rows[2].Cells[2].Value) * 60;
time3 = Convert.ToInt32(this.dataGridView1.Rows[3].Cells[2].Value) * 60;
timer_0 = new DispatcherTimer();
timer_1 = new DispatcherTimer();
timer_2 = new DispatcherTimer();
timer_3 = new DispatcherTimer();
timer_0.Interval = new TimeSpan(0, 0, 1);
timer_1.Interval = new TimeSpan(0, 0, 1);
timer_2.Interval = new TimeSpan(0, 0, 1);
timer_3.Interval = new TimeSpan(0, 0, 1);
timer_0.Tick += TimerFirstRow_Tick;
timer_1.Tick += timer2_Tick_1;
timer_2.Tick += timer3_Tick;
timer_3.Tick += timer4_Tick;
timer_0.Start();
timer_1.Start();
timer_2.Start();
timer_3.Start();
StartButton.Text = "Stop";
timerB = false;
}
}
}
else
{
if (timer_0.IsEnabled)
{
timer_0.Stop();
timerB = false;
StartButton.Text = "Start";
} else if (timer_1.IsEnabled)
{
timer_0.Stop();
timer_1.Stop();
timerB = false;
StartButton.Text = "Start";
} else if (timer_2.IsEnabled)
{
timer_0.Stop();
timer_1.Stop();
timer_2.Stop();
timerB = false;
StartButton.Text = "Start";
} else if (timer_3.IsEnabled)
{
timer_0.Stop();
timer_1.Stop();
timer_2.Stop();
timer_3.Stop();
timerB = false;
StartButton.Text = "Start";
}
}
}
} //Start Timers
I recommend using a single timer, and then subtracting the elapsed time from the original Waiting Time. The important code is in the timer_Tick method:
public class BuildingForm : Form {
DataGridView dgv = new DataGridView();
DataTable table = new DataTable();
Button btnRemoveUpgrade = new Button { Text = "Remove Upgrade" };
Button btnAddBuilding = new Button { Text = "Add Building" };
Button btnStart = new Button { Text = "Start" };
Button btnUpgradeBuilding = new Button { Text = "Upgrade Building" };
Label lbBuilders = new Label { Text = "Builders:", AutoSize = true, Anchor = AnchorStyles.Bottom | AnchorStyles.Left };
Label lbWaitTime = new Label { Text = "Wait Time In:", AutoSize = true, Margin = new Padding(0, 20, 0, 0), Anchor = AnchorStyles.Bottom };
Label lbHours = new Label { Text = "H:", AutoSize = true, Anchor = AnchorStyles.None };
Label lbMinutes = new Label { Text = "M:", AutoSize = true, Anchor = AnchorStyles.None };
NumericUpDown nudHours = new NumericUpDown { Minimum = 0, Maximum = 99, Value = 0, Increment = 1, AutoSize = true };
NumericUpDown nudMinutes = new NumericUpDown { Minimum = 0, Maximum = 59, Value = 1, Increment = 1, AutoSize = true };
NumericUpDown nudBuilders = new NumericUpDown { Minimum = 1, Maximum = 9999, Value = 4, Increment = 1, AutoSize = true };
//---
Timer timer = new Timer { Interval = 1000 };
DateTime utcStartTime = DateTime.MinValue;
DataColumn colBuilding;
DataColumn colToLevel;
DataColumn colWaitingTime;
DataColumn colXY;
List<Data> dataList = new List<Data>();
public BuildingForm() : base() {
this.Size = new Size(800, 600);
this.StartPosition = FormStartPosition.CenterScreen;
dgv.DataSource = table;
dgv.Dock = DockStyle.Fill;
dgv.AllowUserToAddRows = false;
FlowLayoutPanel panel2 = new FlowLayoutPanel { FlowDirection = System.Windows.Forms.FlowDirection.LeftToRight, WrapContents = false, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink };
panel2.Controls.AddRange(new Control[] { lbHours, nudHours, lbMinutes, nudMinutes });
TableLayoutPanel panel1 = new TableLayoutPanel { Dock = DockStyle.Fill, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink };
panel1.Controls.Add(btnRemoveUpgrade, 0, 0); panel1.Controls.Add(btnAddBuilding, 1, 0);
panel1.Controls.Add(btnStart, 0, 1); panel1.Controls.Add(btnUpgradeBuilding, 1, 1);
panel1.Controls.Add(lbBuilders, 0, 2); panel1.Controls.Add(lbWaitTime, 1, 2); panel1.Controls.Add(new Control(), 2, 2);
panel1.Controls.Add(nudBuilders, 0, 3); panel1.Controls.Add(panel2, 1, 3);
TableLayoutPanel panel = new TableLayoutPanel { Dock = DockStyle.Fill };
panel.GrowStyle = TableLayoutPanelGrowStyle.AddColumns;
panel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1f));
panel.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
panel.Controls.Add(dgv, 0, 0);
panel.Controls.Add(panel1, 1, 0);
Controls.Add(panel);
Size sz = btnUpgradeBuilding.PreferredSize;
sz.Width += 20;
sz.Height += 20;
foreach (Control c in new Control[] { btnRemoveUpgrade, btnAddBuilding, btnStart, btnUpgradeBuilding }) {
c.Size = sz;
}
colBuilding = table.Columns.Add("Building");
colToLevel = table.Columns.Add("To Level", typeof(int));
colWaitingTime = table.Columns.Add("Waiting Time:", typeof(TimeSpan));
colXY = table.Columns.Add("X:Y");
table.Rows.Add("Test", 11, TimeSpan.FromMinutes(1), "100:100");
table.Rows.Add("Test", 11, TimeSpan.FromMinutes(10), "100:100");
table.Rows.Add("Test", 11, TimeSpan.FromMinutes(20), "100:100");
table.Rows.Add("Test", 11, TimeSpan.FromMinutes(30), "100:100");
table.Rows.Add("Test", 11, TimeSpan.FromMinutes(90), "100:100");
dgv.BindingContext = new System.Windows.Forms.BindingContext(); // forces dgv columns to be created
dgv.Columns[colWaitingTime.Ordinal].DefaultCellStyle.Format = "hh':'mm':'ss";
btnStart.Click += btnStart_Click;
timer.Tick += timer_Tick;
}
private void timer_Tick(object sender, EventArgs e) {
DateTime utcNow = DateTime.UtcNow;
TimeSpan ellapsed = utcStartTime - utcNow;
for (int i = dataList.Count - 1; i >= 0; i--) {
Data d = dataList[i];
TimeSpan ts = d.tsOrig.Add(ellapsed);
if (ts.Ticks <= 0) {
table.Rows.Remove(d.row);
dataList.RemoveAt(i);
}
else {
d.row[colWaitingTime] = ts;
}
}
dgv.Invalidate();
}
private class Data {
public DataRow row;
public TimeSpan tsOrig;
}
void btnStart_Click(object sender, EventArgs e) {
int numBuilders = (int) nudBuilders.Value;
for (int i = 0; i < numBuilders && i < table.Rows.Count; i++) {
Data d = new Data { row = table.Rows[i], tsOrig = (TimeSpan) table.Rows[i][colWaitingTime] };
dataList.Add(d);
}
utcStartTime = DateTime.UtcNow;
timer.Start();
btnStart.Enabled = false;
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
if (disposing)
timer.Dispose();
}
}

Custom MessageBox with custom-defined Buttons [duplicate]

I am doing C# application, and I want to change the style of a message box. Is it possible or not?
Example: change button style, fore color, etc.
You can't restyle the default MessageBox as that's dependant on the current Windows OS theme, however you can easily create your own MessageBox. Just add a new form (i.e. MyNewMessageBox) to your project with these settings:
FormBorderStyle FixedToolWindow
ShowInTaskBar False
StartPosition CenterScreen
To show it use myNewMessageBoxInstance.ShowDialog();. And add a label and buttons to your form, such as OK and Cancel and set their DialogResults appropriately, i.e. add a button to MyNewMessageBox and call it btnOK. Set the DialogResult property in the property window to DialogResult.OK. When that button is pressed it would return the OK result:
MyNewMessageBox myNewMessageBoxInstance = new MyNewMessageBox();
DialogResult result = myNewMessageBoxInstance.ShowDialog();
if (result == DialogResult.OK)
{
// etc
}
It would be advisable to add your own Show method that takes the text and other options you require:
public DialogResult Show(string text, Color foreColour)
{
lblText.Text = text;
lblText.ForeColor = foreColour;
return this.ShowDialog();
}
MessageBox::Show uses function from user32.dll, and its style is dependent on Windows, so you cannot change it like that, you have to create your own form
Here is the code needed to create your own message box:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MyStuff
{
public class MyLabel : Label
{
public static Label Set(string Text = "", Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color())
{
Label l = new Label();
l.Text = Text;
l.Font = (Font == null) ? new Font("Calibri", 12) : Font;
l.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor;
l.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor;
l.AutoSize = true;
return l;
}
}
public class MyButton : Button
{
public static Button Set(string Text = "", int Width = 102, int Height = 30, Font Font = null, Color ForeColor = new Color(), Color BackColor = new Color())
{
Button b = new Button();
b.Text = Text;
b.Width = Width;
b.Height = Height;
b.Font = (Font == null) ? new Font("Calibri", 12) : Font;
b.ForeColor = (ForeColor == new Color()) ? Color.Black : ForeColor;
b.BackColor = (BackColor == new Color()) ? SystemColors.Control : BackColor;
b.UseVisualStyleBackColor = (b.BackColor == SystemColors.Control);
return b;
}
}
public class MyImage : PictureBox
{
public static PictureBox Set(string ImagePath = null, int Width = 60, int Height = 60)
{
PictureBox i = new PictureBox();
if (ImagePath != null)
{
i.BackgroundImageLayout = ImageLayout.Zoom;
i.Location = new Point(9, 9);
i.Margin = new Padding(3, 3, 2, 3);
i.Size = new Size(Width, Height);
i.TabStop = false;
i.Visible = true;
i.BackgroundImage = Image.FromFile(ImagePath);
}
else
{
i.Visible = true;
i.Size = new Size(0, 0);
}
return i;
}
}
public partial class MyMessageBox : Form
{
private MyMessageBox()
{
this.panText = new FlowLayoutPanel();
this.panButtons = new FlowLayoutPanel();
this.SuspendLayout();
//
// panText
//
this.panText.Parent = this;
this.panText.AutoScroll = true;
this.panText.AutoSize = true;
this.panText.AutoSizeMode = AutoSizeMode.GrowAndShrink;
//this.panText.Location = new Point(90, 90);
this.panText.Margin = new Padding(0);
this.panText.MaximumSize = new Size(500, 300);
this.panText.MinimumSize = new Size(108, 50);
this.panText.Size = new Size(108, 50);
//
// panButtons
//
this.panButtons.AutoSize = true;
this.panButtons.AutoSizeMode = AutoSizeMode.GrowAndShrink;
this.panButtons.FlowDirection = FlowDirection.RightToLeft;
this.panButtons.Location = new Point(89, 89);
this.panButtons.Margin = new Padding(0);
this.panButtons.MaximumSize = new Size(580, 150);
this.panButtons.MinimumSize = new Size(108, 0);
this.panButtons.Size = new Size(108, 35);
//
// MyMessageBox
//
this.AutoScaleDimensions = new SizeF(8F, 19F);
this.AutoScaleMode = AutoScaleMode.Font;
this.ClientSize = new Size(206, 133);
this.Controls.Add(this.panButtons);
this.Controls.Add(this.panText);
this.Font = new Font("Calibri", 12F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Margin = new Padding(4);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new Size(168, 132);
this.Name = "MyMessageBox";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.CenterScreen;
this.ResumeLayout(false);
this.PerformLayout();
}
public static string Show(Label Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
List<Label> Labels = new List<Label>();
Labels.Add(Label);
return Show(Labels, Title, Buttons, Image);
}
public static string Show(string Label, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
List<Label> Labels = new List<Label>();
Labels.Add(MyLabel.Set(Label));
return Show(Labels, Title, Buttons, Image);
}
public static string Show(List<Label> Labels = null, string Title = "", List<Button> Buttons = null, PictureBox Image = null)
{
if (Labels == null) Labels = new List<Label>();
if (Labels.Count == 0) Labels.Add(MyLabel.Set(""));
if (Buttons == null) Buttons = new List<Button>();
if (Buttons.Count == 0) Buttons.Add(MyButton.Set("OK"));
List<Button> buttons = new List<Button>(Buttons);
buttons.Reverse();
int ImageWidth = 0;
int ImageHeight = 0;
int LabelWidth = 0;
int LabelHeight = 0;
int ButtonWidth = 0;
int ButtonHeight = 0;
int TotalWidth = 0;
int TotalHeight = 0;
MyMessageBox mb = new MyMessageBox();
mb.Text = Title;
//Image
if (Image != null)
{
mb.Controls.Add(Image);
Image.MaximumSize = new Size(150, 300);
ImageWidth = Image.Width + Image.Margin.Horizontal;
ImageHeight = Image.Height + Image.Margin.Vertical;
}
//Labels
List<int> il = new List<int>();
mb.panText.Location = new Point(9 + ImageWidth, 9);
foreach (Label l in Labels)
{
mb.panText.Controls.Add(l);
l.Location = new Point(200, 50);
l.MaximumSize = new Size(480, 2000);
il.Add(l.Width);
}
int mw = Labels.Max(x => x.Width);
il.ToString();
Labels.ForEach(l => l.MinimumSize = new Size(Labels.Max(x => x.Width), 1));
mb.panText.Height = Labels.Sum(l => l.Height);
mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight);
mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300);
LabelWidth = mb.panText.Width;
LabelHeight = mb.panText.Height;
//Buttons
foreach (Button b in buttons)
{
mb.panButtons.Controls.Add(b);
b.Location = new Point(3, 3);
b.TabIndex = Buttons.FindIndex(i => i.Text == b.Text);
b.Click += new EventHandler(mb.Button_Click);
}
ButtonWidth = mb.panButtons.Width;
ButtonHeight = mb.panButtons.Height;
//Set Widths
if (ButtonWidth > ImageWidth + LabelWidth)
{
Labels.ForEach(l => l.MinimumSize = new Size(ButtonWidth - ImageWidth - mb.ScrollBarWidth(Labels), 1));
mb.panText.Height = Labels.Sum(l => l.Height);
mb.panText.MinimumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), ImageHeight);
mb.panText.MaximumSize = new Size(Labels.Max(x => x.Width) + mb.ScrollBarWidth(Labels), 300);
LabelWidth = mb.panText.Width;
LabelHeight = mb.panText.Height;
}
TotalWidth = ImageWidth + LabelWidth;
//Set Height
TotalHeight = LabelHeight + ButtonHeight;
mb.panButtons.Location = new Point(TotalWidth - ButtonWidth + 9, mb.panText.Location.Y + mb.panText.Height);
mb.Size = new Size(TotalWidth + 25, TotalHeight + 47);
mb.ShowDialog();
return mb.Result;
}
private FlowLayoutPanel panText;
private FlowLayoutPanel panButtons;
private int ScrollBarWidth(List<Label> Labels)
{
return (Labels.Sum(l => l.Height) > 300) ? 23 : 6;
}
private void Button_Click(object sender, EventArgs e)
{
Result = ((Button)sender).Text;
Close();
}
private string Result = "";
}
}

How do I properly add a custom control to another custom control so that it will render in a form?

I've created a custom control in C#. A highly-simplified version of it is shown below:
class WellControl : Control
{
Pen circlePen = new Pen(Color.Black, 5);
Brush wellShader = new SolidBrush(Color.BlueViolet);
Brush wellBlanker = new SolidBrush(Color.LightGray);
public WellControl(int wellNum)
{
InitializeComponent();
}
private void DrawWell()
{
using (Graphics well = this.CreateGraphics())
{
this.Size = new Size(WellSize, WellSize);
if (this.selected)
{
well.FillEllipse(wellShader, ellipseCoords);
}
else
{
well.FillEllipse(wellBlanker, ellipseCoords);
}
well.DrawEllipse(circlePen, ellipseCoords);
using (Font wellNumberFont = new Font("Arial", 14, FontStyle.Bold))
{
well.DrawString(WellNum.ToString(), wellNumberFont, Brushes.Black, new Point(13, 13));
}
}
}
private void WellPaintEventHandler(object sender, EventArgs e)
{
DrawWell();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(WellPaintEventHandler);
this.ResumeLayout();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
//dispose all the custom stuff
}
}
}
When I add it to a form, it renders properly (again, simplified example):
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int i = 0; i < 4; i++)
{
WellControl newWell = new WellControl(i + 1);
newWell.Location = new Point(15, 50 * i);
newWell.Size = new System.Drawing.Size(45, 45);
this.Controls.Add(newWell);
}
}
}
I have another custom control, "Plate", which is intended to hold many "Wells". The code intended to draw the wells evenly across the plate probably sucks right now but I'm just trying to see something:
class PlateControl : Control
{
Pen blackPen = new Pen(Color.Black, 3);
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
InitializeComponent();
}
private void InitializeComponent()
{
this.SuspendLayout();
this.Paint += new System.Windows.Forms.PaintEventHandler(PlatePaintEventHandler);
this.ResumeLayout();
}
private void DrawPlate()
{
using (Graphics plate = this.CreateGraphics())
{
Point topLeft = new Point(0, 0);
Point topRight = new Point(600, 0);
Point bottomRight = new Point(600, 400);
Point bottomLeft = new Point(0, 400);
plate.DrawLine(blackPen, topLeft, topRight);
plate.DrawLine(blackPen, topRight, bottomRight);
plate.DrawLine(blackPen, bottomRight, bottomLeft);
plate.DrawLine(blackPen, bottomLeft, topLeft);
}
}
private void PlatePaintEventHandler(object sender, EventArgs e)
{
DrawPlate();
}
}
If I add this control to a Winform using this.Controls.Add(new PlateControl()), the rectangle renders, but not the WellControls I added to the PlateControl in the constructor loop. What am I doing incorrectly?
You need to add List of WallControl to plate control.
public PlateControl()
{
this.Size = new Size(600, 800);
List<WellControl> plateWells = new List<WellControl>();
int column = 1;
int row = 0;
for (int i = 1; i <= 96; i++)
{
column = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(i / 8)));
row = i % 8;
WellControl newWell = new WellControl(i + 1);
newWell.Name = "wellControl" + i;
newWell.Location = new Point(column * 50, row * 50);
newWell.Size = new System.Drawing.Size(45, 45);
newWell.TabIndex = i;
newWell.WellSize = 45;
plateWells.Add(newWell);
newWell.Visible = true;
}
this.Controls.AddRange(plateWells.ToArray());
InitializeComponent();
}

WPF Mediaelement.Position is not working

What I need is to set the Position property on WPF's MediaElement control. But when I play the video, (either via Play() or through some kind of animation on Opacity) it is is not working at all. It is showing 00:00:00 time, but I would expect it to be set to 00:00:05.
I have hard-coded Position value and it is not working at all.
Just In case I am going to put all my code I have so u can see the whole animation logic.
Any clue?
public partial class CrossFadeTransition : UserControl
{
DoubleAnimation _doubleAnimationFrontPlayer = new DoubleAnimation();
DoubleAnimation _doubleAnimationBackPlayer = new DoubleAnimation();
Storyboard _sb1 = new Storyboard();
Storyboard _sb2 = new Storyboard();
public TimeSpan Duration = TimeSpan.FromSeconds(2);
public Dictionary<string, Position2D> PlayerPosition { set; get; }
public CrossFadeTransition()
{
InitializeComponent();
Player1.LoadedBehavior = MediaState.Manual;
Player1.UnloadedBehavior = MediaState.Stop;
Player2.LoadedBehavior = MediaState.Manual;
Player2.UnloadedBehavior = MediaState.Stop;
PlayerPosition = new Dictionary<string, Position2D>();
PlayerPosition.Add("Player1", Position2D.Front);
PlayerPosition.Add("Player2", Position2D.Back);
}
Position2D positionPlayer1;
Position2D positionPlayer2;
public void Stop()
{
if (Player1.IsEnabled)
Player1.Stop();
if (Player2.IsEnabled)
Player2.Stop();
}
public void Start(Uri uri, int? position)
{
try
{
positionPlayer1 = PlayerPosition["Player1"];
positionPlayer2 = PlayerPosition["Player2"];
if (positionPlayer1 == Library.Position2D.Back)
{
Player1.Source = uri;
if (Player1.IsEnabled)
Player1.Stop();
Player1.Position = TimeSpan.FromSeconds(5); // IT IS NOT WORKING !!!
Player1.Play();
}
if (positionPlayer2 == Library.Position2D.Back)
{
Player2.Source = uri;
if (Player2.IsEnabled)
Player2.Stop();
Player2.Position = TimeSpan.FromSeconds(5); // IT IS NOT WORKING !!!
Player2.Play();
}
_sb1.Children.Clear();
_sb2.Children.Clear();
if (positionPlayer1 == Position2D.Front)
{
_doubleAnimationFrontPlayer.From = 1;
_doubleAnimationFrontPlayer.To = 0;
_doubleAnimationFrontPlayer.Duration = new Duration(Duration);
PlayerPosition["Player1"] = Position2D.Back;
}
else if (positionPlayer1 == Position2D.Back)
{
_doubleAnimationFrontPlayer.From = 0;
_doubleAnimationFrontPlayer.To = 1;
_doubleAnimationFrontPlayer.Duration = new Duration(Duration);
PlayerPosition["Player1"] = Position2D.Front;
}
if (positionPlayer2 == Position2D.Front)
{
_doubleAnimationBackPlayer.From = 1;
_doubleAnimationBackPlayer.To = 0;
_doubleAnimationBackPlayer.Duration = new Duration(Duration);
PlayerPosition["Player2"] = Position2D.Back;
}
else if (positionPlayer2 == Position2D.Back)
{
_doubleAnimationBackPlayer.From = 0;
_doubleAnimationBackPlayer.To = 1;
_doubleAnimationBackPlayer.Duration = new Duration(Duration);
PlayerPosition["Player2"] = Position2D.Front;
}
_sb1.Children.Add(_doubleAnimationFrontPlayer);
Storyboard.SetTargetProperty(_doubleAnimationFrontPlayer, new PropertyPath("(Panel.Opacity)"));
Storyboard.SetTarget(_doubleAnimationFrontPlayer, Player1);
_sb1.Completed += _sb1_Completed;
_sb1.Begin();
//
_sb2.Children.Add(_doubleAnimationBackPlayer);
Storyboard.SetTargetProperty(_doubleAnimationBackPlayer, new PropertyPath("(Panel.Opacity)"));
Storyboard.SetTarget(_doubleAnimationBackPlayer, Player2);
_sb2.Completed += _sb2_Completed;
_sb2.Begin();
}
catch (Exception)
{
throw;
}
}
void _sb2_Completed(object sender, EventArgs e)
{
_sb2.Completed -= _sb2_Completed;
Debug.WriteLine("Player2 COMPLETED " + DateTime.Now.TimeOfDay);
if (positionPlayer2 == Position2D.Front)
{
Player2.Stop();
}
}
void _sb1_Completed(object sender, EventArgs e)
{
_sb1.Completed -= _sb1_Completed;
Debug.WriteLine("Player1 COMPLETED " + DateTime.Now.TimeOfDay);
if (positionPlayer1 == Position2D.Front)
{
Player1.Stop();
}
}
}
I have tried to do like
Player2.Play();
Player2.Pause();
Player2.Position = TimeSpan.FromSeconds(5); // IT IS NOT WORKING !!!
Player2.Play();
But no joy...
I found some solution. It is not completely ideal because sometimes it shows the first video frame, but at least it is working.
We need those events where we can apply new Position.
void Player2_MediaOpened(object sender, RoutedEventArgs e)
{
Player2.Position = new TimeSpan(0, 0, 7);
}
void Player1_MediaOpened(object sender, RoutedEventArgs e)
{
Player1.Position = new TimeSpan(0, 0, 7);
}
We have to close Mediaelement like this.
Player1.Stop();
Player1.Close();
Player1.Source = uri;
Player1.Play();
Have fun! (beer)

Custom DataGridView problem with bottom line

I faced with the problem with custom DataGridView. I want to draw a bottom line, but I can't avoid of drawing this line that remain on cells when I scrolling the grid.
public partial class GridTest : DataGridView
{
private static Color _gridColor = Color.FromArgb(219, 225, 232);
private int gridHeight;
private bool resizing;
private const int Xoffset = 5;
private const int Yoffset = 10;
Color cl1 = Color.FromArgb(255, 255, 255);
Color cl2 = Color.FromArgb(229, 233, 238);
Color cl3 = Color.FromArgb(234, 237, 242);
Color cl4 = Color.FromArgb(170, 186, 208);
private Color _clrColumnHeader;
public Color ColorColumnHeader
{
get { return _clrColumnHeader; }
set { _clrColumnHeader = value; }
}
public GridTest()
{
InitializeComponent();
Init();
}
public GridTest(IContainer container)
{
container.Add(this);
InitializeComponent();
Init();
}
private void Init()
{
var _headerHeight = 50;
ColumnHeadersHeight = _headerHeight;
BackgroundColor = Color.White;
RowTemplate.Height += 5;
AllowUserToAddRows = false;
AllowUserToDeleteRows = false;
AllowUserToResizeColumns = false;
AllowUserToResizeRows = false;
AutoResizeRows(DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders);
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
RowHeadersVisible = false;
MultiSelect = false;
ReadOnly = true;
AutoGenerateColumns = false;
EnableHeadersVisualStyles = false;
ShowCellErrors = false;
ShowEditingIcon = false;
ShowRowErrors = false;
}
private Blend gradientBlend()
{
float[] myFactors = { 0.0f, .00f, .8f, 1.0f };
float[] myPositions = { 0.0f, .4f, .8f, 1.0f };
var myBlend = new Blend {Factors = myFactors, Positions = myPositions};
return myBlend;
}
private void DrawGradientOnHeader(DataGridViewCellPaintingEventArgs e)
{
var newRect = new Rectangle(e.CellBounds.X+1, e.CellBounds.Y, e.CellBounds.Width -1, e.CellBounds.Height-1);
var gradient = new LinearGradientBrush(newRect, cl1, cl2, LinearGradientMode.Vertical);
gradient.Blend = gradientBlend();
e.Graphics.FillRectangle(gradient, newRect);
gradient.Dispose();
}
private static void DrawWhiteLine(DataGridViewCellPaintingEventArgs e, int x, int offset)
{
var brush = new SolidBrush(Color.White);
var pen = new Pen(brush);
int y = e.CellBounds.Y;
int x1 = x + offset;
int y1 = e.CellBounds.Height - 1;
var pt1 = new Point(x1, y);
var pt2 = new Point(x1, y1);
e.Graphics.DrawLine(pen, pt1, pt2);
brush.Dispose();
pen.Dispose();
}
private void DrawSeparators(DataGridViewCellPaintingEventArgs e)
{
DrawWhiteLine(e,e.CellBounds.Right,-1);
DrawWhiteLine(e, e.CellBounds.Left,1);
int x = e.CellBounds.X;
int y = e.CellBounds.Y;
int y1 = e.CellBounds.Height - 1;
var newRect2 = new Rectangle(x, y, 1, y1);
var gradient = new LinearGradientBrush(newRect2, cl3, cl4, LinearGradientMode.Vertical);
gradient.Blend = gradientBlend();
e.Graphics.FillRectangle(gradient, newRect2);
gradient.Dispose();
}
private static void DrawLines(DataGridViewCellPaintingEventArgs e)
{
var brush= new SolidBrush(Color.FromArgb(170, 186, 208));
var pen = new Pen(brush);
//Верхняя линяя над хидером
e.Graphics.DrawLine(pen, e.CellBounds.X, e.CellBounds.Top , e.CellBounds.Right, e.CellBounds.Top );
//Нижняя линия под хидером
e.Graphics.DrawLine(pen, e.CellBounds.X, e.CellBounds.Bottom - 1, e.CellBounds.Right, e.CellBounds.Bottom-1);
brush.Dispose();
pen.Dispose();
}
private void DrawText(DataGridViewCellPaintingEventArgs e)
{
var clr_font = _clrColumnHeader;
var rect = new Rectangle(e.CellBounds.X + Xoffset, e.CellBounds.Y + Yoffset, e.CellBounds.Width,
e.CellBounds.Height);
var formatFlags = TextFormatFlags.WordBreak;
if (e.Value != null)
{
try
{
TextRenderer.DrawText(e.Graphics, (String)e.Value, e.CellStyle.Font, rect, clr_font, formatFlags);
}
catch
{
TextRenderer.DrawText(e.Graphics, "", e.CellStyle.Font, rect, clr_font, formatFlags);
}
}
}
private void EraseTheCell(DataGridViewCellPaintingEventArgs e)
{
using (Brush backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
}
}
protected override void OnColumnWidthChanged(DataGridViewColumnEventArgs e)
{
base.OnColumnWidthChanged(e);
Invalidate();
}
private int oldRowIndex = 0;
protected override void OnCurrentCellChanged(EventArgs e)
{
base.OnCurrentCellChanged(e);
if (oldRowIndex != -1)
{
InvalidateRow(oldRowIndex);
}
oldRowIndex = CurrentCellAddress.Y;
}
protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
base.OnCellPainting(e);
if (e.RowIndex == -1) // Рисуем ColumnHeader
{
EraseTheCell(e);
DrawGradientOnHeader(e);
DrawSeparators(e);
DrawText(e);
DrawLines(e);
e.Handled = true;
}
//e.CellStyle.BackColor = Color.White;
}
protected override void PaintBackground(Graphics graphics, Rectangle clipBounds, Rectangle gridBounds)
{
base.PaintBackground(graphics, clipBounds, gridBounds);
var brush = new SolidBrush(Color.Black);
var pen = new Pen(brush);
var y_crd = clipBounds.Bottom - 10;
var x_crd = clipBounds.Right;
graphics.FillRectangle(brush, clipBounds);
var newbounds = new Rectangle
{
X = clipBounds.X,
Y = clipBounds.Y,
Width = clipBounds.Width,
Height = clipBounds.Height - 1
};
var brushWhite = new SolidBrush(Color.White);
graphics.FillRectangle(brushWhite, newbounds);
//graphics.DrawLine(pen, 0, y_crd, x_crd, y_crd);
brush.Dispose();
pen.Dispose();
}
}

Categories