How to change cursor in custom control? - c#

Here is my custom WebBrowser control.
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class RunescapeClient : WebBrowser
{
private const string RUNESCAPE_CLIENT_URL = "http://oldschool33.runescape.com/j1";
public RunescapeClient()
{
ScrollBarsEnabled = false;
ScriptErrorsSuppressed = true;
IsWebBrowserContextMenuEnabled = false;
AllowWebBrowserDrop = false;
Navigate(RUNESCAPE_CLIENT_URL);
}
protected override void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)
{
if (Document != null && ValidClientUrl(e.Url.ToString()))
{
HtmlElement tableElement = Document.GetElementsByTagName("table")[1];
tableElement.InnerText = string.Empty;
}
}
private static bool ValidClientUrl(string url)
{
return Regex.IsMatch(url, #"http://oldschool\d{1,2}.runescape.com/j1");
}
}
How can I change the cursor for this control to my embedded .ico. I googled and couldn't find anything for custom controls.
Thanks.

The cursor is always changed by the Cursor property. It doesn't matter if you have a custom control.
Try this:
Icon ico = new Icon(#"C:\temp\someIcon.ico");
this.Cursor = new Cursor(ico.Handle);
The static class System.Windows.Forms.Cursors contains all system cursors.
To switch back to the default system cursor, use this:
this.Cursor = System.Windows.Forms.Cursors.Default;

Related

Acumatica Styling a specific column/cell in PXView?

I am VERY new to Acumatica in coding. I am trying to change the color of a cell on the header page of AR303000. (see code below). Obviously this is not working. I receive the error message of PXFormViewEventArgs does not exist in the namespace PX.Web.UI.
Can anyone direct me as to what namespace I should be using and correct my code to make this work?
Thank you,
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using PX.Common;
using PX.Data;
using PX.SM;
using PX.Objects.AR.CCPaymentProcessing;
using PX.Objects.AR.Repositories;
using PX.Objects.Common;
using PX.Objects.Common.Discount;
using PX.Objects.CA;
using PX.Objects.CM;
using PX.Objects.CR;
using PX.Objects.CR.Extensions;
using PX.Objects.CS;
using PX.Objects.SO;
using PX.Objects.AR.CCPaymentProcessing.Helpers;
using PX.Data.BQL.Fluent;
using PX.Data.BQL;
using PX.Data.Descriptor;
using CashAccountAttribute = PX.Objects.GL.CashAccountAttribute;
using PX.Objects.GL.Helpers;
using PX.Objects.TX;
using PX.Objects.IN;
using PX.Objects.CR.Extensions.Relational;
using PX.Objects.CR.Extensions.CRCreateActions;
using PX.Objects.GDPR;
using PX.Objects.GraphExtensions.ExtendBAccount;
using PX.Data.ReferentialIntegrity.Attributes;
using CRLocation = PX.Objects.CR.Standalone.Location;
using PX.Objects;
using PX.Objects.AR;
namespace PX.Objects.AR
{
public class CustomerMaint_Extension : PXGraphExtension<CustomerMaint>
{
protected void Page_Load(object sender, EventArgs e)
{
Style escalated = new Style();
escalated.ForeColor = System.Drawing.Color.Red;
this.Page.Header.StyleSheet.CreateStyleRule(escalated, this, ".CssEscalated");
Style rowStyle = new Style();
rowStyle.BackColor = System.Drawing.Color.Red;
this.Page.Header.StyleSheet.CreateStyleRule(rowStyle, this, ".CssRowStyle");
Style cellStyle = new Style();
cellStyle.BackColor = System.Drawing.Color.Aqua;
this.Page.Header.StyleSheet.CreateStyleRule(cellStyle, this, ".CssCellStyle");
Style highlightStyle = new Style();
highlightStyle.BackColor = System.Drawing.Color.Yellow;
this.Page.Header.StyleSheet.CreateStyleRule(highlightStyle, this, ".CssHighlightStyle");
}
protected void Customer_RowSelected(PXCache sender, PXRowSelectedEventArgs e, PX.Web.UI.PXFormViewEventArgs f)
{
var customer = (CR.BAccount)e.Row;
var customerExt = customer.GetExtension<CR.BAccountExt>();
if (customerExt != null)
{
/*I want to change the color of this cell in the form*/
customerExt.UsrReadOnlyAcctName = customer.AcctName;
}
}
#region Event Handlers
#endregion
}
}```
I think you can detect the Form and the control of the UsrReadonlyAcctName and then apply the Css style during Page_Load; below is an example, but in my case, I find a Grid and then detect a Cell's value during RowDataBound:
public override void Initialize()
{
//Access page via http context current handler
Page page = HttpContext.Current?.Handler as PXPage;
if (page != null)
{
page.Load += Page_Load;
}
}
private void Page_Load(object sender, EventArgs e)
{
Page page = (Page)sender;
RegisterStyle(page, "MyCssRed", "#FD9999 !important", null, false);
PX.Web.UI.PXGrid grdMyGridControl = (PX.Web.UI.PXGrid)ControlHelper.FindControl("grid2", page); // Allocations popup
if (grdMyGridControl != null)
{
grdMyGridControl.RowDataBound += (object grdsender, PXGridRowEventArgs erdb) =>
{
var data = erdb.Row;
if (data == null) { return; }
bool isRed = false;
PXGridCell cell = data.Cells["INItemLotSerialKvExt__ValueString"];
if (cell == null) return;
Object value = cell.Value;
if (value != null && (String)value == "R")
{
isRed = true;
}
...
if (isRed)
data.Style.CssClass = "MyCssRed";
Patrick Chen supplies a helpful reference.
EDIT ANSWER:
Below is an example on the Sales Order page SO301000 that finds the "Customer Order Nbr" TextBox and adds color when its Text is empty:
private void Page_Load(object sender, EventArgs e)
{
Page page = (Page)sender;
RegisterStyle(page, "MyCssRed", "#FD9999 !important", null, false);
PX.Web.UI.PXTextEdit myBox = (PX.Web.UI.PXTextEdit)ControlHelper.FindControl("edCustomerOrderNbr", page);
if (myBox != null)
{
myBox.DataBinding += (object boxsender, EventArgs boxargs) =>
{
PX.Web.UI.PXTextEdit box = boxsender as PX.Web.UI.PXTextEdit;
string cellText = box.Text;
box.CssClass = string.IsNullOrEmpty(cellText) ? "MyCssRed" : "editor";
};
}

How do I get the value of NotifyIcon.Icon property programmatically?

I know this is such a noob question, but I am trying to learn and test. One of my self-imposed challenges is creating a NotifyIcon in the systray (easy) and then clicking a button and making the icon change on interval from green to red based on the current icon value. However, when I try to read the value of NotifyIcon.Icon, it is just (Icon). I expect it to be an ico file I have in Properties.Resources (i.e. Properties.Resources.icon.ico).
using System;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
namespace TEST_NotifyIconChange
{
public partial class MainWindow : Window
{
private NotifyIcon notifyIcon = new NotifyIcon();
private ContextMenuStrip ContextMenuStrip_System_Tray = new ContextMenuStrip();
private DispatcherTimer iconAnimationTimer = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
iconAnimationTimer.Interval = TimeSpan.FromSeconds(1);
iconAnimationTimer.Tick += IconAnimationTimer_Tick;
iconAnimationTimer.IsEnabled = false;
ResetAll();
}
private void ResetAll()
{
notifyIcon.ContextMenuStrip = ContextMenuStrip_System_Tray;
notifyIcon.Icon = Properties.Resources.icon_green;
notifyIcon.Text = "I am just a standard icon";
notifyIcon.Visible = true;
}
private void ChangeColorButton_Click(object sender, RoutedEventArgs e)
{
if (iconAnimationTimer.IsEnabled == false)
{
iconAnimationTimer.IsEnabled = true;
iconAnimationTimer.Start();
}
else
{
iconAnimationTimer.Stop();
iconAnimationTimer.IsEnabled = false;
}
}
private void IconAnimationTimer_Tick(object sender, EventArgs e)
{
if (notifyIcon.Icon == Properties.Resources.icon_green)
{
Console.WriteLine("Changing to red");
notifyIcon.Icon = Properties.Resources.icon_red;
}
else
{
Console.WriteLine("Changing to green");
notifyIcon.Icon = Properties.Resources.icon_green;
}
}
}
}
notifyIcon.Icon == Properties.Resources.icon_green will never return true, because every time that you call it, it returns a new instance of the Icon.
You don't need to track the assigned icon; instead, you need to track of the status and based on the status, assign an icon. To track the status you can use Tag property of NotifyIcon or a member field of the Form. But do not look at the Icon property as a status indicator.
Just in case you are interested to compare two Icon objects to see whether they are same icon, you can use the following method:
bool AreIconsEqual(Icon ico1, Icon ico2)
{
byte[] bytes1, bytes2;
using (var fs = new MemoryStream())
{
ico1.Save(fs);
bytes1 = fs.ToArray();
}
using (var fs = new MemoryStream())
{
ico2.Save(fs);
bytes2 = fs.ToArray();
}
return bytes1.SequenceEqual(bytes2);
}

How can i save settings of my app to a text file and read them back on load?

Read them back in app constructor and also maybe in other places in program.
I have a new form i created with some checkboxes:
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 System.IO;
namespace Options
{
public partial class OptionsMenuForm : Form
{
public OptionsMenuForm()
{
InitializeComponent();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
Settings.downloadonstart = true;
}
else
{
Settings.downloadonstart = false;
}
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked)
{
Settings.loadonstart = true;
}
else
{
Settings.loadonstart = false;
}
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
Settings.startminimized = true;
}
else
{
Settings.startminimized = false;
}
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
if (checkBox4.Checked)
{
Settings.displaynotifications = true;
}
else
{
Settings.displaynotifications = false;
}
}
}
}
Now i want to save each time the state of one/any of the checkboxes.
I also added a class i'm using th pass the variables between the new form and form1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Options
{
class Settings
{
public static bool downloadonstart;
public static bool loadonstart;
public static bool startminimized;
public static bool displaynotifications;
}
}
Now how can i use this in form1 by saving the settings to a text file ?
For example in the text file the content will be something like:
CheckBox1 = true
CheckBox2 = false
CheckBox3 = false
CheckBox4 = true
And then if i change the state of one of them it will write it in the text file:
CheckBox1 = false
CheckBox2 = false
CheckBox3 = true
CheckBox4 = true
In form1 top i added
string settingsFile = "settings.txt";
string settingsFileDirectory = "\\settings";
StreamWriter writetosettingsfile;
Then in constructor
settingsFileDirectory = Path.GetDirectoryName(Application.LocalUserAppDataPath) +
settingsFileDirectory;
if (!Directory.Exists(settingsFileDirectory))
{
Directory.CreateDirectory(settingsFileDirectory);
}
I know the app it self have a settings in the properties but i wanted to use a text file this time since i have many settings and i might have more later.
Or using the settings in the app in properties i did:
But now how do i use with it in my program to save every checkbox state in the new form and then using it in form1 ?
You can use json.net
Something like this to save the data
private void Form1_Load(object sender, EventArgs e)
{
checkBox1.CheckedChanged += checkBox_CheckedChanged;
checkBox2.CheckedChanged += checkBox_CheckedChanged;
checkBox3.CheckedChanged += checkBox_CheckedChanged;
checkBox4.CheckedChanged += checkBox_CheckedChanged;
}
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
var settings = new Settings();
settings.downloadonstart = checkBox1.Checked;
settings.loadonstart = checkBox2.Checked;
settings.startminimized = checkBox3.Checked;
settings.displaynotifications = checkBox4.Checked;
File.WriteAllText(#"c:\configfile.json", JsonConvert.SerializeObject(settings));
}
You can read the file like this
Settings settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(#"c:\configfile.json"));
Documentation:
http://www.newtonsoft.com/json/help/html/Introduction.htm
public OptionsMenuForm()
{
InitializeComponent();
//Read the settings from a file with comma delimited 1's and 0's or whatever you like
string[] values = System.IO.File.ReadAllText("c:\temp\a.txt").Split(',');
checkBox1.Checked = Convert.ToBoolean(Convert.ToInt32(values[0]));
checkBox2.Checked = Convert.ToBoolean(Convert.ToInt32(values[1]));;
//On checkbox changes save the settings
checkBox1.CheckedChanged +=SaveSettings;
checkBox2.CheckedChanged +=SaveSettings;
}
public void SaveSettings(object sender,EventArgs e)
{
StringBuilder sbValues = new StringBuilder();
int i = 0;
i = checkBox1.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
i = checkBox2.Checked ? 1 : 0;
sbValues.Append(i.ToString() + ",");
System.IO.File.WriteAllText("c:\temp\a.txt",sbValues.ToString());
}
It is recommended that you use XML when using the .NET framework.
public static void ConvertStringToXmlList()
{
XElement xml = new XElement
(
"Items",
(
from x in [YourList] select new XElement("Item", x)
)
);
XDocument doc = new XDocument
(
xml
);
doc.Save(Environment.CurrentDirectory + "/settings.xml");
}
var xmlReader = new XmlTextReader("settings.xml");
while (xmlReader.Read())
{
switch (reader.NodeType)
{
case [nodetype]:
// Code here
break;
}
}
Also, instead of creating the same event for all four checkbox's, just use 1.
Inside of the single event put:
ckCheckBox1.Checked = !ckCheckBox1.Checked;

I'm trying to change the color of each of a set of buttons using C#/Visual studio but nothing happens

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;
namespace Cameron_PickerillTrinitapoli_Assn1
{
public partial class seasonalBttnChanger : Form
{
public seasonalBttnChanger()
{
InitializeComponent();
}
//Triggers when program first loads
//Sets up
private void bttnChanger_Load(object sender, EventArgs e)
{
List<Button> lstTxt = new List<Button>
{
bttnSpring, bttnSummer, bttnAutumn, bttnWinter
};
//Wiring up event handlers in run time
foreach (Button txt in lstTxt)
{
txt.MouseEnter += button_MouseEnter;
txt.MouseLeave += button_MouseLeave;
}
}
// Sets up different background colors for TextBoxes
//* Static values for the color of each button need
//to be added.
//**Not what I was trying to accomplish
//**This needs to go somewhere else
void button_MouseEnter(object sender, EventArgs e)
{
try
{
// Event handlers always pass the parameter "sender" in as an object.
// You have to downcast it back to the actual type.
String bttnName = null;
String bttnNameSpring = "Spring";
String bttnNameSummer = "Summer";
String bttnNameAutumn = "Autumn";
String bttnNameWinter = "Winter";
Button txt = (Button)sender;
// stkColor.Push(txt.BackColor);
//txt.BackColor = Color.Red;
bttnName = txt.Name;
if (bttnName == bttnNameSpring)
{
txt.BackColor = Color.LightGreen;
}
else if (bttnName == bttnNameSummer)
{
//txt.BackColor = Color.Red;
txt.BackColor = Color.Red;
}
else if (bttnName == bttnNameAutumn)
{
txt.BackColor = Color.Yellow;
}
else if (bttnName == bttnNameWinter)
{
txt.BackColor = Color.Cyan;
}
}
catch (Exception ex)
{
MessageBox.Show("Error:\n " + ex.Message);
}
}
//Handler for mouse leaving the button
void button_MouseLeave(object sender, EventArgs e)
{
try
{
Button txt = (Button)sender;
//txt.BackColor = stkColor.Pop();
}
catch (Exception ex)
{
MessageBox.Show("Error:\n " + ex.Message);
}
}
}
}
}
Alright, so I'm just trying to create a simple program that changes the background colors of these buttons to some plain colors when you mouse over them. I had the same thing working using TextBox, but I need to get it working with button. I changed everything over to use the Button class, and it seems to have all the same functionality, but now the program runs, but nothing happens when you mouse over the buttons.
I'm pretty new to c#, stack exchange, and only slightly less so to programming in general, so sorry if I'm dinking up on etiquette/formatting my questions, etc.
I think you are trying to reference your buttons title when you are actually calling the button name
Changing:
String bttnName = null;
String bttnNameSpring = "Spring";
String bttnNameSummer = "Summer";
String bttnNameAutumn = "Autumn";
String bttnNameWinter = "Winter";
Button txt = (Button)sender;
To:
String bttnName = null;
String bttnNameSpring = "bttnSpring";
String bttnNameSummer = "bttnSummer";
String bttnNameAutumn = "bttnAutumn";
String bttnNameWinter = "bttnWinter";
Causes the code to work.
If you do infact want to use the "Spring", "Summer" etc reference than i would suggest changing
bttnName = txt.Name;
to
bttnName = txt.Text;
And ensure that the Text of the labels is set correctly

Controlling IE from C#?

How can I control IE form C#? I know that via COM you can do all sorts of interesting stuff, but looking at the SHDocVw namespace once I import the reference into my project there doesn't seem to be that many methods. For example, how would I force a button to be clicked? Or set or read the value of a specific control on a page? In general, how can I individually control an object in IE though .NET?
Here are some samples from code I've written to control IE, maybe it can help:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
//...
void SetField(WebBrowser wb, string formname, string fieldname, string fieldvalue) {
HtmlElement f = wb.Document.Forms[formname].All[fieldname];
f.SetAttribute("value", fieldvalue);
}
void SetRadio(WebBrowser wb, string formname, string fieldname, bool isChecked) {
HtmlElement f = wb.Document.Forms[formname].All[fieldname];
f.SetAttribute("checked", isChecked ? "True" : "False");
}
void SubmitForm(WebBrowser wb, string formname) {
HtmlElement f = wb.Document.Forms[formname];
f.InvokeMember("submit");
}
void ClickButtonAndWait(WebBrowser wb, string buttonname,int timeOut) {
HtmlElement f = wb.Document.All[buttonname];
webReady = false;
f.InvokeMember("click");
DateTime endTime = DateTime.Now.AddSeconds(timeOut);
bool finished = false;
while (!finished) {
if (webReady)
finished = true;
Application.DoEvents();
if (aborted)
throw new EUserAborted();
Thread.Sleep(50);
if ((timeOut != 0) && (DateTime.Now>endTime)) {
finished = true;
}
}
}
void ClickButtonAndWait(WebBrowser wb, string buttonname) {
ClickButtonAndWait(wb, buttonname, 0);
}
void Navigate(string url,int timeOut) {
webReady = false;
webBrowser1.Navigate(url);
DateTime endTime = DateTime.Now.AddSeconds(timeOut);
bool finished = false;
while (!finished) {
if (webReady)
finished = true;
Application.DoEvents();
if (aborted)
throw new EUserAborted();
Thread.Sleep(50);
if ((timeOut != 0) && (DateTime.Now > endTime)) {
finished = true;
}
}
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
webReady = true;
}
This might help.
This maybe a good place to start. I know it's aimed at unit testing, but it automates control over IE and firefox and it's open source so you can download the code to see how they do it.
Hope it helps

Categories