I'm using WPF application and I have reminder every hour from 7 AM tell 3 PM every day, it is running every hour even if the user closed the window it still show up after one hour using DispatcherTimer.
my issue is after 3 PM it closed and it keep checking tell next day to count one hour after 7 AM to display the window but it is not.
it display directly after 7 AM. how I can fixed it, please assist
my code:
public partial class MainWindow : Window
{
public int _mCollapsed;
public Window1 WindowLink1;
public ReminderWin ReminderWin1;
public TimeSpan start = new TimeSpan(7, 0, 0);
public TimeSpan end = new TimeSpan(15, 0, 0);
public MainWindow()
{
InitializeComponent();
_mCollapsed = 1;
WindowLink1 = new Window1();
ReminderWin1 = new ReminderWin();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
TimeSpan now = DateTime.Now.TimeOfDay;
if (now > start)
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Interval = new TimeSpan(1, 0, 0);
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
TimeSpan now = DateTime.Now.TimeOfDay;
if ((now > start) && (now < end))
{
BitmapImage _image = new BitmapImage();
_image.BeginInit();
_image.UriSource = new Uri(#"test123.jpg", UriKind.RelativeOrAbsolute);
_image.UriCachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
_image.CacheOption = BitmapCacheOption.OnLoad;
_image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
_image.EndInit();
ReminderWin1.image1.Source = _image;
System.Diagnostics.Debug.WriteLine(ReminderWin1.WindowState);
if (ReminderWin1.Visibility == Visibility.Collapsed || ReminderWin1.Visibility == Visibility.Hidden)
{
ReminderWin1.Visibility = System.Windows.Visibility.Visible;
}
}
else if (now > end)
{
if (ReminderWin1.Visibility == Visibility.Visible || ReminderWin1.Visibility == Visibility.Hidden)
{
ReminderWin1.Close();
}
}
}
}
Related
I am trying to hide my ChromiumWebBrowser behind images, video, etc... But every time it changes from a ChromiumWebBrowser to anything else than a blank panel or another ChromiumWebBrowser it flashes black for a few frames.
Exemple of my problem
hardware:
i7-8559U
intel IRI plus Graphics 655
CefSharp Version 79.1.350 for a Winform Program
Here is what I tried:
BringToFront other PictureBox
SendToback the ChromiumWebBrowser
Panel visibility
Panel doubleBuffed
I also enable Cef.EnableHighDPISupport(); but to no success.
The only thing that worked so far is to ADD
SetOffScreenRenderingBestPerformanceArgs();
But unfortunately, it disables WebGL implementation :/ and I would like to keep it for later purposes.
static class Program
{
/// <summary>
/// Point d'entrée principal de l'application.
/// </summary>
[STAThread]
static void Main()
{
Cef.EnableHighDPISupport();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
public partial class Form1 : Form
{
private static ChromiumWebBrowser chrome;
private PictureBox ImageBox = new PictureBox();
private Panel pPictureBox = new Panel();
private Panel pChromium = new Panel();
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
ImageBox.Image = Properties.Resources._3080;
ImageBox.SizeMode = PictureBoxSizeMode.StretchImage;
pPictureBox.Controls.Add(ImageBox);
ImageBox.Dock = DockStyle.Fill;
pPictureBox.Dock = DockStyle.Fill;
pPictureBox.Size = this.Size;
this.Controls.Add(pPictureBox);
pPictureBox.BringToFront();
InitializeChromium();
timer.Interval = 7000;
timer.Start();
timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, EventArgs e)
{
if (pChromium.Visible)
{
pChromium.Hide();
}
else
{
pChromium.Show();
}
}
private void InitializeChromium()
{
pChromium.Dock = DockStyle.Fill;
pChromium.Size = this.Size;
CefSettings settings = new CefSettings();
//Work but disable WebGL
//settings.SetOffScreenRenderingBestPerformanceArgs();
//settings.DisableGpuAcceleration();
Cef.Initialize(settings);
chrome = new ChromiumWebBrowser("https://www.apple.com/ca/airpods-pro/");
pChromium.Controls.Add(chrome);
this.Controls.Add(pChromium);
chrome.Dock = DockStyle.Fill;
pChromium.BringToFront();
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(1904, 1041);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Cef.Shutdown();
}
}
Do you guys have any solution?
Here is my final code for any one interested
Links of the command recommanded by #amaitland
https://peter.sh/experiments/chromium-command-line-switches/#use-angle
https://peter.sh/experiments/chromium-command-line-switches/#in-process-gpu
both command works individualy
Cef.EnableHighDPISupport(); is not required but is recommanded
static void Main()
{
Cef.EnableHighDPISupport();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public partial class Form1 : Form
{
private static ChromiumWebBrowser chrome;
private PictureBox ImageBox = new PictureBox();
private Panel pPictureBox = new Panel();
private Panel pChromium = new Panel();
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
//any image here
ImageBox.Image = Properties.Resources._3080;
ImageBox.SizeMode = PictureBoxSizeMode.StretchImage;
pPictureBox.Controls.Add(ImageBox);
ImageBox.Dock = DockStyle.Fill;
pPictureBox.Dock = DockStyle.Fill;
pPictureBox.Size = this.Size;
this.Controls.Add(pPictureBox);
pPictureBox.BringToFront();
InitializeChromium();
timer.Interval = 7000;
timer.Start();
timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, EventArgs e)
{
if (pChromium.Visible)
{
pChromium.Hide();
}
else
{
pChromium.Show();
}
}
private void InitializeChromium()
{
pChromium.Dock = DockStyle.Fill;
pChromium.Size = this.Size;
CefSettings settings = new CefSettings();
//-------------------------------------------------------------------------
settings.CefCommandLineArgs.Add("in-process-gpu");
//got best FPS with this renderer on "my machine"
settings.CefCommandLineArgs.Add("use-angle", "gl");
//-------------------------------------------------------------------------
//Work but disable WebGL
//settings.SetOffScreenRenderingBestPerformanceArgs();
//settings.DisableGpuAcceleration();
Cef.Initialize(settings);
chrome = new ChromiumWebBrowser("https://alteredqualia.com/three/examples/webgl_pasta.html");
pChromium.Controls.Add(chrome);
this.Controls.Add(pChromium);
chrome.Dock = DockStyle.Fill;
pChromium.BringToFront();
}
private void InitializeComponent()
{
this.SuspendLayout();
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(1904, 1041);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Cef.Shutdown();
}
}
Hi all my simple code looks like this
private void flipForeverever(object sender, EventArgs args)
{
moveYs = new DoubleAnimation();
m2oveYs = new DoubleAnimation();
try
{
sf.Remove(this);
sf.Children.Clear();
}
catch (Exception e)
{
}
if (firstPanelAngle == 360)
{
moveYs.To = 180;
moveYs.From = 0;
}
else
{
moveYs.To = 360;
moveYs.From = 180;
}
if (secondPanelAngle == 360)
{
m2oveYs.To = 180;
m2oveYs.From = 0;
}
else
{
m2oveYs.To = 360;
m2oveYs.From = 180;
}
sf = (Storyboard)FindResource("Storyboard1");
Storyboard.SetTargetName(moveYs, "rotatePanel");
Storyboard.SetTargetProperty(moveYs, new thisPropertyPath(AxisAngleRotation3D.AngleProperty));
Storyboard.SetTargetName(m2oveYs, "rotateSecond");
Storyboard.SetTargetProperty(m2oveYs, new PropertyPath(AxisAngleRotation3D.AngleProperty));
sf.Children.Add(moveYs);
sf.Children.Add(m2oveYs);
// sf.RepeatBehavior = RepeatBehavior.Forever;
if (flipForever)
{
sf.Completed += new EventHandler(delaythespin);
sf.Begin(this);
}
}
private void delaythespin(object sender, EventArgs args)
{
sf.Stop(this);
System.Timers.Timer timer = new System.Timers.Timer(500);
timer.Elapsed += new System.Timers.ElapsedEventHandler(flipForeverever);
timer.Enabled = true;
firstPanelAngle = rotatePanel.Angle;
secondPanelAngle = rotateSecond.Angle;
timer.Start();
}
So basically i call flipForeverever through a click call and it is supposed to loop forever until i set flipforever to false... But then it is giving me this error...
The calling thread cannot access this object because a different thread owns it.
Any help will really be appreciated
It sounds like you might be having thread affinity problems. Have you tried using a DispatcherTimer instead of a System.Timers.Timer?
private DispatcherTimer _timer;
private void GoButton_Click(object sender, RoutedEventArgs e)
{
_timer = new DispatcherTimer(); // create timer
_timer.Interval = new TimeSpan(0, 0, 1); // tick every 1s
_timer.Tick += new EventHandler(_timer_Tick); // method to call
_timer.Start(); // start timer
}
void _timer_Tick(object sender, EventArgs e)
{
// we should be on the correct thread now
GoButton.Background = Brushes.Aqua;
}
Or, if you need to use System.Timers.Timer, use Invoke or BeginInvoke to get on the correct thread after the timer fires?
private System.Timers.Timer _timer;
private void GoButton_Click(object sender, RoutedEventArgs e)
{
_timer = new System.Timers.Timer(1000);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
}
void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// use Dispatcher.Invoke on the UI object that you want to modify
// to get on the correct thread for that UI object
GoButton.Dispatcher.Invoke((ThreadStart)(() =>
{
GoButton.Background = Brushes.Aqua;
}));
}
If I start my form, write something in my textbox and then try to get the textbox value, then I get null. How can I get the textbox value? If I add a button and try to get the value, then it works. But I'm trying to do it without the button. I am using a WPF form. This is my code:
public partial class _2band : Page
{
public _2band()
{
InitializeComponent();
UpdateLayout();
RFIDI();
vardasBox1.Text = "";
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
// MainWondow mainas = new MainWondow();
DB db = new DB();
string pavad;
string vardas;
int status;
string s = "";
string s0 = "";
RfidApi Api = new RfidApi();
private System.Windows.Threading.DispatcherTimer dispatcherTimer;
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
Api.nuskaitymas(out s0);
if (s0 != null)
{
s = s0;
vardas = vardasBox1.Text;
}
}
In my Application I have two buttons "open" and "close".
When I click open button window will be opened, when I click close button window will be closed.
When I click open button 3 times, 3 windows will be opened. I want to close all window when I click close button.
Here is my code [Please don't try to Change the Thread because that is my requirement in my Application]
public partial class MainWindow : Window
{
Window ProgressWindow;
Thread ProgressThread;
public MainWindow()
{
InitializeComponent();
}
private void Open_Click(object sender, RoutedEventArgs e)
{
ProgressThread = new Thread(() =>
{
ProgressWindow = new Window();
ProgressWindow.Margin = new Thickness(0, 0, 50, 0);
ProgressWindow.WindowState = WindowState.Normal;
ProgressWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
ProgressWindow.Height = 180;
ProgressWindow.Width = 180;
ProgressWindow.Content = "Hello WPF";
ProgressWindow.ShowInTaskbar = false;
ProgressWindow.Show();
ProgressWindow.Closed += (sender2, e2) =>
ProgressWindow.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
ProgressThread.SetApartmentState(ApartmentState.STA);
ProgressThread.Start();
}
private void Close_Click(object sender, RoutedEventArgs e)
{
if (ProgressThread.IsAlive == true)
{
ProgressThread.Abort();
}
}
}
I would recommend to store references to created windows, your code can look like this:
Stack<Window> ProgressWindow=new Stack<Window>();
Thread ProgressThread;
private void Open_Click(object sender, RoutedEventArgs e)
{
ProgressThread = new Thread(() =>
{
var window = new Window();
window.Margin = new Thickness(0, 0, 50, 0);
window.WindowState = WindowState.Normal;
window.WindowStartupLocation = WindowStartupLocation.CenterScreen;
window.Height = 180;
window.Width = 180;
window.Content = "Hello WPF";
window.ShowInTaskbar = false;
window.Show();
window.Closed += (sender2, e2) =>
window.Dispatcher.InvokeShutdown();
ProgressWindow.Push(window);
System.Windows.Threading.Dispatcher.Run();
});
ProgressThread.SetApartmentState(ApartmentState.STA);
ProgressThread.Start();
}
private void Close_Click(object sender, RoutedEventArgs e)
{
while (ProgressWindow.Count > 0)
{
ProgressWindow.Pop().Close();
}
}
thread aborting is not recommended if it is "normal" workflow of your application, i.e. window wasn't closed because of some critical error
I wouldn't recommend what you are doing and actually I don't really know if it works like this, but since you stated that it's your (strange) requirement to use threads like this, I will only comment on the actual problem:
You should save the threads in a List and then close all the threads from this list.
Edit:
public partial class MainWindow : Window
{
Window ProgressWindow;
List<Thread> ProgressThreads = new List<Thread>();
public MainWindow()
{
InitializeComponent();
}
private void Open_Click(object sender, RoutedEventArgs e)
{
ProgressThreads.Add(new Thread(() =>
{
ProgressWindow = new Window();
ProgressWindow.Margin = new Thickness(0, 0, 50, 0);
ProgressWindow.WindowState = WindowState.Normal;
ProgressWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;
ProgressWindow.Height = 180;
ProgressWindow.Width = 180;
ProgressWindow.Content = "Hello WPF";
ProgressWindow.ShowInTaskbar = false;
ProgressWindow.Show();
ProgressWindow.Closed += (sender2, e2) =>
ProgressWindow.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
}));
ProgressThread.SetApartmentState(ApartmentState.STA);
ProgressThread.Start();
}
private void Close_Click(object sender, RoutedEventArgs e)
{
foreach(var ProgressThread in ProgressThreads)
{
if (ProgressThread.IsAlive == true)
{
ProgressThread.Abort();
}
}
}
}
You will need to keep a record of all threads you have opened when you click "Open". Then in your "Close" method loop over that list closing each one.
Member variable:
List<Thread> allThreads = new List<Thread>();
Then in your open handler add:
allThreads.Add(ProgressThread);
Then your close handler becomes:
foreach (Thread thread in allThreads)
{
if (thread.IsAlive)
{
thread.Abort();
}
}
That what you are trying is unorthodox should go without saying.
Every time timer ticks the application keep on using extra memory.
How to dispose the handle in GetActeWindowTitle() and window2?
How should i manage the memory usage for this?
my Code :
public partial class Window1 : Window
{
Window2 window2 ;
System.Windows.Forms.Timer timer1;
public Window1()
{
InitializeComponent();
timer1 = new Timer();
timer1.Interval = 900000;
timer1.Tick += new EventHandler(timer1Tick);
timer1.Start();
}
private void timer1Tick( object Sender, EventArgs e )
{
window2 = new window2Window();
if (((GetActeWindowTitle().IndexOf("Outlook") != -1) ||
(GetActeWindowTitle().IndexOf("Word") != -1)))
{
window2.Close();
}
else
{
window2.Show();
window2.Topmost = true;
}
}
private string GetActeWindowTitle()
{
const int nChars = 256;
IntPtr handle = IntPtr.Zero;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
}
Maybe by releasing the memory that gets allocated from that Interop call referenced in the IntPtr.
Try this after using you handle in GetActeWindowTitle():
Marshal.FreeCoTaskMem(handle);
Why create new window2Window only to close it?
// window2 = new window2Window();
if (((GetActeWindowTitle().IndexOf("Outlook") != -1) ||
(GetActeWindowTitle().IndexOf("Word") != -1)))
{
// window2.Close();
}
else
{
window2 = new window2Window();
window2.Show();
window2.Topmost = true;
}