Aforge PictureBox throws "System.InvalidOperationException: 'The object is currently in use elsewhere.'" when I resize or move the application window.
In some situations it throws an Exception that indicates the use in several threads.
Exception
Main Code:
public partial class MainForm : Form
{
//Global Var
String[] serialLog = new String[300];
SerialLogDisplay sld_form;
FilterInfoCollection filterInfoCollection;
VideoCaptureDevice videoCaptureDevice;
//Form Method
public MainForm()
{
InitializeComponent();
}
//Generated Methods
private void btnCCamera_Click(object sender, EventArgs e)
{
if(cmbCameraS.SelectedIndex > 0) {
disconnectVideoStream(false);
videoCaptureDevice = new VideoCaptureDevice(filterInfoCollection[cmbCameraS.SelectedIndex-1].MonikerString);
videoCaptureDevice.NewFrame += VideoCaptureDevice_NewFrame;
videoCaptureDevice.Start();
Add_Log("Camera \"" + filterInfoCollection[cmbCameraS.SelectedIndex-1].Name+ "\" Connected!");
}
else
{
disconnectVideoStream(true);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//Camera System
cmbCameraS.Items.Add("None");
filterInfoCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo filterInfo in filterInfoCollection)
{
cmbCameraS.Items.Add(filterInfo.Name);
}
cmbCameraS.SelectedIndex = 0;
videoCaptureDevice = new VideoCaptureDevice();
//Log
shortLog.Parent = cameraDisplay;
shortLog.BackColor = Color.Transparent;
shortLog.Text = serialLog[0] + "\n" + serialLog[1] + "\n" + serialLog[2];
//Loop
Timer tmr = new Timer();
tmr.Interval = 1000;
tmr.Tick += Tmr_Tick;
tmr.Start();
//DisplayObjects
MPpanel.Parent = cameraDisplay;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
disconnectVideoStream(false);
}
private void SLbtn_Click(object sender, EventArgs e)
{
if (sld_form == null)
{
sld_form = new SerialLogDisplay(this);
}
sld_form.update_log(serialLog);
sld_form.Show();
sld_form.Activate();
}
//Created Methods
//Serial Log
private void Tmr_Tick(object sender, EventArgs e)
{
String lm = "";
for (int i = 4; i >= 0; i--)
{
if (serialLog[i] != null)
{
lm += serialLog[i] + "\n";
}
}
shortLog.Text = lm;
}
public void SerialLogDisplay_Close()
{
sld_form = null;
}
public void Add_Log(String text)
{
for (int i = serialLog.Length - 1; i > 0; i--)
{
serialLog[i] = serialLog[i - 1];
}
serialLog[0] = text;
if(sld_form != null)
{
sld_form.update_log(serialLog);
}
}
public void Serial_Command(String command)
{
Add_Log(command);
//Send command to serial Port
}
//Camera Output
private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
try
{
if (cameraDisplay.Image != null)
{
cameraDisplay.Image.Dispose();
}
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
cameraDisplay.Image = bmp;
}
catch (System.InvalidOperationException ex)
{
Add_Log("Error: " + ex);
disconnectVideoStream(true);
}
//GC.Collect();
}
private void disconnectVideoStream(bool showLog)
{
if (videoCaptureDevice.IsRunning == true)
{
if (showLog) { Add_Log("Disconnecting video stream..."); }
videoCaptureDevice.SignalToStop();
videoCaptureDevice.WaitForStop();
videoCaptureDevice.Stop();
cameraDisplay.Image = null;
}
if (showLog)
{
Add_Log("No camera connected!");
}
GC.Collect();
}
}
"CameraDysplay" -> PictureBox
I tried to put the Bitmap image as global, but it didn't work...
I also tried blocking the application window size change, but the error remains...
I tried to use invoke and it worked, but it crashes when closing the application.
private void VideoCaptureDevice_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Invoke(new Action(() => {
try
{
if (cameraDisplay.Image != null)
{
cameraDisplay.Image.Dispose();
}
Bitmap bmp = (Bitmap)eventArgs.Frame.Clone();
cameraDisplay.Image = bmp;
}
catch (System.InvalidOperationException ex)
{
Add_Log("Error: " + ex);
disconnectVideoStream(true);
}
}));
//GC.Collect();
}
I am developing an application which can identify basic shapes and their colors. Identifying shape part is done Now I want to identify the color of that shapes.I am using EmguCV libraries. Is there any one help me?
Shape Detection and Color Filtering in Emgu CV
This is the edited code in C# (According to the previously mentioned video in visual basic)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
namespace EmguCVShapeDetector
{
public partial class Form1 : Form
{
//---Variables--//
bool blnFirstTimeInResizeEvent = true;
int OriginalFormWidth;
int OriginalFormHeight;
int OriginalTableLayoutPanelWidth;
int OriginalTableLayoutPanelHeight;
Capture capwebcam;
bool webCamCapturingInProcess = false;
Image<Bgr, Byte> imgOriginal;
Image<Bgr, Byte> imgSmoothed;
Image<Gray, Byte> imgGrayColorFiltered;
Image<Gray, Byte> imgCanny;
Image<Bgr, Byte> imgCircles;
Image<Bgr, Byte> imgLines;
Image<Bgr, Byte> imgTrisRectsPolys;
Double dbMinBlue = 0.0;
double dbMinGreen = 0.0;
double dbMinRed = 0.0;
double dbMaxBlue = 0.0;
double dbMaxGreen = 0.0;
double dbMaxRed = 0.0;
public Form1()
{
InitializeComponent();
OriginalFormWidth = this.Width;
OriginalFormHeight = this.Height;
OriginalTableLayoutPanelWidth = tlpLebelsAndImageBoxes.Width;
OriginalTableLayoutPanelHeight = tlpLebelsAndImageBoxes.Height;
}
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i <= 255; i++)
{
cmbMinBlue.Items.Add(i);
cmbMinGreen.Items.Add(i);
cmbMinRed.Items.Add(i);
cmbMaxBlue.Items.Add(i+1);
cmbMaxGreen.Items.Add(i+1);
cmbMaxRed.Items.Add(i+1);
}
cmbMinBlue.Text = "0";
cmbMinGreen.Text = "0";
cmbMinRed.Text = "0";
cmbMaxBlue.Text = "1";
cmbMaxGreen.Text = "1";
cmbMaxRed.Text = "1";
}
private void Form1_Resize(object sender, EventArgs e)
{
if(blnFirstTimeInResizeEvent == true)
{
blnFirstTimeInResizeEvent = false;
}
else
{
tlpLebelsAndImageBoxes.Width = this.Width - (OriginalTableLayoutPanelWidth);
tlpLebelsAndImageBoxes.Height = this.Height - (OriginalTableLayoutPanelHeight);
}
}
private void radImageFile_CheckedChanged(object sender, EventArgs e)
{
if(radImageFile.Checked == true)
{
if(webCamCapturingInProcess == true)
{
Application.Idle -= ProcessImageAndUpdateGUI;
webCamCapturingInProcess = false;
}
ibOriginal.Image = null;
ibGrayColorFilter.Image = null;
ibCanny.Image = null;
ibCircles.Image = null;
ibLines.Image = null;
ibTrianglesAndPolys.Image = null;
lblFile.Visible = true;
txtFile.Visible = true;
btnFile.Visible = true;
}
}
private void radWebCam_CheckedChanged(object sender, EventArgs e)
{
if(radWebCam.Checked == true)
{
try
{
capwebcam = new Capture();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
Application.Idle += ProcessImageAndUpdateGUI;
webCamCapturingInProcess = true;
lblFile.Visible = false;
txtFile.Visible = false;
btnFile.Visible = false;
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if(capwebcam != null)
{
capwebcam.Dispose();
}
}
private void btnFile_Click(object sender, EventArgs e)
{
if (ofdFile.ShowDialog() == DialogResult.OK)
{
Image inputImage = Image.FromFile(ofdFile.FileName);
txtFile.Text = ofdFile.FileName.ToString();
}
}
private void chbDrawCirclesOnOriginalImage_CheckedChanged(object sender, EventArgs e)
{
if(webCamCapturingInProcess == false)
{
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void chbDrawLinesOnOriginalImage_CheckedChanged(object sender, EventArgs e)
{
if (webCamCapturingInProcess == false)
{
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void chbDrawTrianglesAndPolygansOnOriginalImage_CheckedChanged(object sender, EventArgs e)
{
if (webCamCapturingInProcess == false)
{
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void chbFillterOnColor_CheckedChanged(object sender, EventArgs e)
{
if(chbFillterOnColor.Checked == true)
{
lblBlue.Visible = true;
lblGreen.Visible = true;
lblRed.Visible = true;
lblMin.Visible = true;
lblMax.Visible = true;
cmbMinBlue.Visible = true;
cmbMinGreen.Visible = true;
cmbMinRed.Visible = true;
cmbMaxBlue.Visible = true;
cmbMaxGreen.Visible = true;
cmbMaxRed.Visible = true;
lblGrayColorFilter.Text = "gray (color filtered):";
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
else if (chbFillterOnColor.Checked == false)
{
lblBlue.Visible = false;
lblGreen.Visible = false;
lblRed.Visible = false;
lblMin.Visible = false;
lblMax.Visible = false;
cmbMinBlue.Visible = false;
cmbMinGreen.Visible = false;
cmbMinRed.Visible = false;
cmbMaxBlue.Visible = false;
cmbMaxGreen.Visible = false;
cmbMaxRed.Visible = false;
lblGrayColorFilter.Text = "gray:";
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void txtFile_TextChanged(object sender, EventArgs e)
{
txtFile.SelectionStart = txtFile.Text.Length;
}
private void cmbMinBlue_SelectedIndexChanged(object sender, EventArgs e)
{
if(chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMinBlue = Convert.ToDouble(cmbMinBlue.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMinGreen_SelectedIndexChanged(object sender, EventArgs e)
{
if (chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMinGreen = Convert.ToDouble(cmbMinGreen.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMinRed_SelectedIndexChanged(object sender, EventArgs e)
{
if (chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMinRed = Convert.ToDouble(cmbMinRed.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMaxBlue_SelectedIndexChanged(object sender, EventArgs e)
{
if (chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMaxBlue = Convert.ToDouble(cmbMaxBlue.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMaxGreen_SelectedIndexChanged(object sender, EventArgs e)
{
if (chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMaxGreen = Convert.ToDouble(cmbMaxGreen.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMaxRed_SelectedIndexChanged(object sender, EventArgs e)
{
if (chbFillterOnColor.Checked == true && txtFile.Text != "")
{
dbMaxRed = Convert.ToDouble(cmbMaxRed.Text);
ProcessImageAndUpdateGUI(new object(), new EventArgs());
}
}
private void cmbMinBlue_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMinBlue.Text) < 0 || Convert.ToInt32(cmbMinBlue.Text) > 255)
{
cmbMinBlue.Text = "0";
}
cmbMinBlue_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMinGreen_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMinGreen.Text) < 0 || Convert.ToInt32(cmbMinGreen.Text) > 255)
{
cmbMinGreen.Text = "0";
}
cmbMinGreen_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMinRed_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMinRed.Text) < 0 || Convert.ToInt32(cmbMinRed.Text) > 255)
{
cmbMinRed.Text = "0";
}
cmbMinRed_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMaxBlue_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMaxBlue.Text) < 1 || Convert.ToInt32(cmbMaxBlue.Text) > 256)
{
cmbMaxBlue.Text = "1";
}
cmbMaxBlue_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMaxGreen_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMaxGreen.Text) < 1 || Convert.ToInt32(cmbMaxGreen.Text) > 256)
{
cmbMaxGreen.Text = "1";
}
cmbMaxGreen_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMaxRed_Leave(object sender, EventArgs e)
{
if (Convert.ToInt32(cmbMaxRed.Text) < 1 || Convert.ToInt32(cmbMaxRed.Text) > 256)
{
cmbMaxRed.Text = "1";
}
cmbMaxRed_SelectedIndexChanged(new object(), new EventArgs());
}
private void cmbMinBlue_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
private void cmbMinGreen_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
private void cmbMinRed_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
private void cmbMaxBlue_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
private void cmbMaxGreen_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
private void cmbMaxRed_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter) || e.KeyCode.Equals(Keys.Return))
{
e.SuppressKeyPress = true;
lblOriginal.Focus();
}
}
void ProcessImageAndUpdateGUI(object sender, EventArgs e)
{
if(radImageFile.Checked == true)
{
try
{
imgOriginal = new Image<Bgr,Byte>(txtFile.Text);
}
catch (Exception ex)
{
return;
}
}
else if(radWebCam.Checked == true)
{
try
{
imgOriginal = capwebcam.QueryFrame();
}
catch (Exception ex)
{
return;
}
}
if(imgOriginal == null)
{
return;
}
imgSmoothed = imgOriginal.PyrDown().PyrUp();
imgSmoothed._SmoothGaussian(3);
if(chbFillterOnColor.Checked == true)
{
imgGrayColorFiltered = imgSmoothed.InRange(new Bgr(dbMinBlue,dbMinGreen,dbMinRed),new Bgr(dbMaxBlue,dbMaxGreen,dbMaxRed));
imgGrayColorFiltered = imgGrayColorFiltered.PyrDown().PyrUp();
imgGrayColorFiltered._SmoothGaussian(3);
}
else if(chbFillterOnColor.Checked == false)
{
imgGrayColorFiltered = imgSmoothed.Convert<Gray, Byte>();
}
Gray grayCannyThreshold = new Gray(160);
Gray grayCircleAccumThreshold = new Gray(100);
Gray grayThreshLinking = new Gray(80);
imgCanny = imgGrayColorFiltered.Canny(grayCannyThreshold, grayThreshLinking);
imgCircles = imgOriginal.CopyBlank();
imgLines = imgOriginal.CopyBlank();
imgTrisRectsPolys = imgOriginal.CopyBlank();
Double dblAccumRes = 2.0;
Double dblMinDistBetweenCircles = imgGrayColorFiltered.Height / 4;
int intMinRadius = 10;
int intMaxRadius = 400;
CircleF[] circles = imgGrayColorFiltered.HoughCircles(grayCannyThreshold, grayCircleAccumThreshold, dblAccumRes, dblMinDistBetweenCircles, intMinRadius, intMaxRadius)[0];
foreach(CircleF circle in circles)
{
imgCircles.Draw(circle, new Bgr(Color.Red),2);
if(chbDrawCirclesOnOriginalImage.Checked == true)
{
imgCircles.Draw(circle, new Bgr(Color.Red), 2);
}
}
Double dblRhoRes = 1.0;
Double dblThetaRes = 4.0 *(Math.PI/180.0);
int intThreshold = 20;
Double dblMinLineWidth = 30.0;
Double dblMinGapBetweenLines = 10.0;
LineSegment2D[] lines = imgCanny.Clone().HoughLinesBinary(dblRhoRes, dblThetaRes, intThreshold, dblMinLineWidth, dblMinGapBetweenLines)[0];
foreach(LineSegment2D line in lines)
{
imgLines.Draw(line, new Bgr(Color.DarkGreen),2);
if(chbDrawLinesOnOriginalImage.Checked == true)
{
imgOriginal.Draw(line, new Bgr(Color.DarkGreen),2);
}
}
Contour<Point> contours = imgCanny.FindContours();
List<Triangle2DF> lstTreangles = new List<Triangle2DF>();
List<MCvBox2D> lstRectangles = new List<MCvBox2D>();
List<Contour<Point>> lstPoluhons = new List<Contour<Point>>();
while(contours != null)
{
Contour<Point> contour = contours.ApproxPoly(10.0);
if(contour.Area > 250.0)
{
if(contour.Total == 3)
{
Point[] ptPoints = contour.ToArray();
lstTreangles.Add(new Triangle2DF(ptPoints[0],ptPoints[1],ptPoints[2]));
}
else if(contour.Total >= 4 && contour.Total <= 6)
{
Point[] ptPoints = contour.ToArray();
Boolean blnIsRectangle = true;
if(contour.Total == 4)
{
LineSegment2D[] ls2dEdges = PointCollection.PolyLine(ptPoints, true);
for(int i = 0; i< ls2dEdges.Length -1; i++)
{
Double dblAngle = Math.Abs(ls2dEdges[(i+1) % ls2dEdges.Length].GetExteriorAngleDegree(ls2dEdges[i]));
if(dblAngle < 80.0 || dblAngle > 100.0)
{
blnIsRectangle = false;
}
}
}
else
{
blnIsRectangle = false;
}
if(blnIsRectangle)
{
lstRectangles.Add(contour.GetMinAreaRect());
}
else
{
lstPoluhons.Add(contour);
}
}
}
contours = contours.HNext;
}
foreach(Triangle2DF triangle in lstTreangles)
{
imgTrisRectsPolys.Draw(triangle, new Bgr(Color.Yellow),2);
if(chbDrawTrianglesAndPolygansOnOriginalImage.Checked == true)
{
imgOriginal.Draw(triangle, new Bgr(Color.Yellow),2);
}
}
foreach(MCvBox2D rect in lstRectangles)
{
imgTrisRectsPolys.Draw(rect, new Bgr(Color.Blue),2);
if(chbDrawTrianglesAndPolygansOnOriginalImage.Checked == true)
{
imgOriginal.Draw(rect, new Bgr(Color.Blue),2);
}
}
foreach(Contour<Point> contPoly in lstPoluhons)
{
imgTrisRectsPolys.Draw(contPoly, new Bgr(Color.Gray),2);
if(chbDrawTrianglesAndPolygansOnOriginalImage.Checked == true)
{
imgOriginal.Draw(contPoly, new Bgr(Color.Gray),2);
}
}
ibOriginal.Image = imgOriginal;
ibGrayColorFilter.Image = imgGrayColorFiltered;
ibCanny.Image = imgCanny;
ibLines.Image = imgLines;
ibTrianglesAndPolys.Image = imgTrisRectsPolys;
}
}
}
I think this code will helpful to your project.
I am trying to pass a string from Form2.cs to Form1.cs and then display it in a message box. For some reason, the variable in the string is not showing but the rest of the text is.
Form1.cs
Form2 otherForm = new Form2();
public void getOtherTextBox()
{
otherForm.TextBox1.Text = player1;
}
private void labelClick(object sender, EventArgs e)
{
Label clickedLabel = (Label)sender;
if (clickedLabel.BackColor != Color.Transparent)
{
return;
}
clickedLabel.BackColor = isBlackTurn ? Color.Black : Color.White;
isBlackTurn = !isBlackTurn;
Color? winner = WinCheck.CheckWinner(board);
if (winner == Color.Black)
{
MessageBox.Show( player1 + " is the winner!");
}
else if (winner == Color.White)
{
MessageBox.Show("White is the winner!");
}
else
{
return;
}
Form2.cs
public TextBox TextBox1
{
get
{
return textBox1;
}
}
this might work .. u need to call the function somewhere to make it work.
I fixed it by calling it in the label click;
so u need to click the label to update the value in the other form.
u can add this function to events like a timer event which ensures that it's always updated within a perfect time.
public void getOtherTextBox()
{
otherForm.TextBox1.Text = player1;
}
private void labelClick(object sender, EventArgs e)
{
Label clickedLabel = (Label)sender;
getOtherTextBox();
if (clickedLabel.BackColor != Color.Transparent)
{
return;
}
clickedLabel.BackColor = isBlackTurn ? Color.Black : Color.White;
isBlackTurn = !isBlackTurn;
Color? winner = WinCheck.CheckWinner(board);
if (winner == Color.Black)
{
MessageBox.Show( player1 + " is the winner!");
}
else if (winner == Color.White)
{
MessageBox.Show("White is the winner!");
}
else
{
return;
}
}
You can create a property in Form1 to hold the player name, and then in Form2, when the input of player name changed, you will update the property of Form1. See the code:
public class Form1()
{
//Code
private string PlayerName { get; set; }
private void labelClick(object sender, EventArgs e)
{
Label clickedLabel = (Label)sender;
if (clickedLabel.BackColor != Color.Transparent)
return;
clickedLabel.BackColor = isBlackTurn ? Color.Black : Color.White;
isBlackTurn = !isBlackTurn;
Color? winner = WinCheck.CheckWinner(board);
if (winner == Color.Black)
MessageBox.Show(this._playerName + " is the winner!");
else if (winner == Color.White)
MessageBox.Show("White is the winner!");
}
//More code
}
public class Form2()
{
private Form1 _frm;
public Form2()
{
this._frm = new Form1();
}
public void ShowFormWinner()
{
_frm.PlayerName = textBox1.Text;
_frm.Show();
}
public void OnPlayerNameChanged(object sender, EventArgs e)
{
_frm.PlayerName = textBox1.Text;
_frm.Show();
}
}
I am trying to implement Fast app resume for Windows Phone 8. I followed the link at MSDN.
And here is the code in XAML:
<Tasks>
<DefaultTask Name="_default" NavigationPage="MainPage.xaml" ActivationPolicy="Resume"/>
</Tasks>
And this is the code in app.xaml.cs
public static PhoneApplicationFrame RootFrame { get; private set; }
bool wasRelaunched = false;
bool mustClearPagestack = false;
IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
enum SessionType
{
None,
Home,
DeepLink
}
private SessionType sessionType = SessionType.None;
public App()
{
UnhandledException += Application_UnhandledException;
InitializeComponent();
InitializePhoneApplication();
InitializeLanguage();
if (Debugger.IsAttached)
{
Application.Current.Host.Settings.EnableFrameRateCounter =true;
PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}
}
private void Application_Launching(object sender, LaunchingEventArgs e)
{
RemoveCurrentDeactivationSettings();
}
private void Application_Activated(object sender, ActivatedEventArgs e)
{
mustClearPagestack = CheckDeactivationTimeStamp();
if (!e.IsApplicationInstancePreserved)
{
RestoreSessionType();
}
}
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
SaveCurrentDeactivationSettings();
}
private void Application_Closing(object sender, ClosingEventArgs e)
{
RemoveCurrentDeactivationSettings();
}
private void RootFrame_NavigationFailed(object sender, NavigationFailedEventArgs e)
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
}
private void Application_UnhandledException(object sender,ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
}
private bool phoneApplicationInitialized = false;
private void InitializePhoneApplication()
{
if (phoneApplicationInitialized)
return;
RootFrame= new PhoneApplicationFrame();
RootFrame.Background = new SolidColorBrush(Color.FromArgb(255, 27, 200, 174));
RootFrame.Navigated += CompleteInitializePhoneApplication;
RootFrame.NavigationFailed += RootFrame_NavigationFailed;
RootFrame.Navigated += CheckForResetNavigation;
RootFrame.Navigating += RootFrame_Navigating;
phoneApplicationInitialized = true;
}
void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (e.Uri.ToString().Contains(#"/MainPage.xaml") == true && !AppPrefManager.Instance.IsFastAppResumeEnabled)
{
RootFrame.Dispatcher.BeginInvoke(delegate
{
if (!AppPrefManager.Instance.IsVirginLaunchCompleted)
{
RootFrame.Navigate(new Uri(Constants.kIntroPage, UriKind.Relative));
}
else
{
RootFrame.Navigate(new Uri(Constants.kMainPage, UriKind.Relative));
}
});
e.Cancel = true;
}
if (sessionType == SessionType.None && e.NavigationMode == NavigationMode.New)
{
if (e.Uri.ToString().Contains("DeepLink=true"))
{
sessionType = SessionType.DeepLink;
}
else if (e.Uri.ToString().Contains("/MainPage.xaml"))
{
sessionType = SessionType.Home;
}
}
if (e.NavigationMode == NavigationMode.Reset)
{
wasRelaunched = true;
}
else if (e.NavigationMode == NavigationMode.New && wasRelaunched)
{
wasRelaunched = false;
if (e.Uri.ToString().Contains("DeepLink=true"))
{
sessionType = SessionType.DeepLink;
}
else if (e.Uri.ToString().Contains("/MainPage.xaml"))
{
if (sessionType == SessionType.DeepLink)
{
sessionType = SessionType.Home;
}
else
{
if (!mustClearPagestack)
{
e.Cancel = true;
RootFrame.Navigated -= ClearBackStackAfterReset;
}
}
}
mustClearPagestack = false;
}
}
private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
{
if (RootVisual != RootFrame)
RootVisual = RootFrame;
RootFrame.Navigated -= CompleteInitializePhoneApplication;
}
private void CheckForResetNavigation(object sender, NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Reset)
RootFrame.Navigated += ClearBackStackAfterReset;
}
private void ClearBackStackAfterReset(object sender, NavigationEventArgs e)
{
RootFrame.Navigated -= ClearBackStackAfterReset;
if (e.NavigationMode != NavigationMode.New && e.NavigationMode != NavigationMode.Refresh)
return;
while (RootFrame.RemoveBackEntry() != null)
{
;
}
}
private void InitializeLanguage()
{
try
{
FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection);
RootFrame.FlowDirection = flow;
}
catch
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
throw;
}
}
bool CheckDeactivationTimeStamp()
{
DateTimeOffset lastDeactivated;
if (settings.Contains("DeactivateTime"))
{
lastDeactivated = (DateTimeOffset)settings["DeactivateTime"];
}
var currentDuration = DateTimeOffset.Now.Subtract(lastDeactivated);
return TimeSpan.FromSeconds(currentDuration.TotalSeconds) > TimeSpan.FromSeconds(30);
}
public bool AddOrUpdateValue(string Key, Object value)
{
bool valueChanged = false;
if (settings.Contains(Key))
{
if (settings[Key] != value)
{
settings[Key] = value;
valueChanged = true;
}
}
else
{
settings.Add(Key, value);
valueChanged = true;
}
return valueChanged;
}
public void RemoveValue(string Key)
{
if (settings.Contains(Key))
{
settings.Remove(Key);
}
}
public void SaveCurrentDeactivationSettings()
{
if (AddOrUpdateValue("DeactivateTime", DateTimeOffset.Now))
{
settings.Save();
}
if (AddOrUpdateValue("SessionType", sessionType))
{
settings.Save();
}
}
public void RemoveCurrentDeactivationSettings()
{
RemoveValue("DeactivateTime");
RemoveValue("SessionType");
settings.Save();
}
void RestoreSessionType()
{
if (settings.Contains("SessionType"))
{
sessionType = (SessionType)settings["SessionType"];
}
}
Suppose while I am in ThirdPage. I press the Windows button. And then I press my App icon from the start screen. Rather than the app resuming from the ThirdPage. It first shows the ThirdPage and then starts from the MainPage.
By default, the app still navigates to the default page, when the application is launched via the app tile.
You can check the session type in the RootFrame_Navigated methods and cancel that navigation, if you so wish.
The default template adds a CheckNavigation method to in the app.xaml.cs that clears the backstack after a navigation with NavigationMode Reset.
You can check there, if your app should stay on the last page or if it is better to reset and start over.
A sample for handling different activation types can be found here:
MSDN Fast Resume Sample, App.xaml.cs
(Method: RootFrame_Navigated)
Code as listed will mess up. It doesn't match the comments.
Look at the RootFrame_Navigating - mustClearPagesStack at the bottom is set to false - but look at the comments in the original MSDN link - two places above it say the page stack must be cleared.... but because the flag is set to false it's messed up. So set the flag false at the top, but then set it to true in the two 'if conditions' where it says to.
Then it will work like a champ.
I'm new to c# and I tried making a simple program. After I click the button, the values won't update with their actual value, so I have to click twice to make them actually work. Here's my code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private static int p;
private static int money;
public Form1()
{
InitializeComponent();
p = 0;
money = 100;
}
private void button1_Click(object sender, EventArgs e)
{
m.Text = money.ToString();
ex.Text = p.ToString();
if (checkBox1.Checked && checkBox2.Checked)
{
MessageBox.Show("You cannot select both.", "Nope");
}
else if (checkBox1.Checked)
{
p += 2;
}
else if (checkBox2.Checked)
{
money -= 50;
p += 10;
}
else
{
return;
}
}
}
}
You need to update the text after updating the value
if (checkBox1.Checked & checkBox2.Checked)
{
MessageBox.Show("You cannot select both.", "Nope");
}
....
m.Text = money.ToString();
ex.Text = p.ToString();