what I want is, after recording the mouse movement and saving the coordinates/ indexes/ position, I will have to load the mouse coordinates and make the mouse move according to the loaded coordinates
i don't have code to show you because am stuck at this point
' private void button3_Click_1(object sender, EventArgs e)
{
StreamWriter writer;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
string[] cvsArray = new string[10000];
saveFileDialog1.Filter = "All files (*.All)|*.All|All files (*.*)|*.*";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
writer = File.CreateText(saveFileDialog1.FileName);
// if ((myStream = saveFileDialog1.OpenFile()) != null)
//{
for (int i = 0; i < cvsArray.Length; i++)
{
string text = richTextBox1.Text;
writer.WriteLine(text);
}
// Code to write the stream goes here.
writer.Close();
//}
}
}
private void button11_Click(object sender, EventArgs e)
{
StreamReader reader;
string Line;
string[] cvsArray;
string position;
//set the filter to dialog control
openFileDialog1.Filter = FILTER;
//check if the user selected the right file
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
//open the selected file
reader = File.OpenText(openFileDialog1.FileName);
//Read the entireline form the file
Line = reader.ReadLine();
//read while it is still not the end of the file
while (!reader.EndOfStream)
{
Line = reader.ReadLine();
//Splite the line using array
cvsArray = Line.Split(':');
position = cvsArray[0];
//position = cvsArray[1];
listBox1.Items.Add(position);
}
}
}'
This is a quick and rather dirty solution:
Let's start with a few varibles:
List<Point> points = null;
Timer tt = null;
int index = 0;
Now a button to start the recoding; it initializes a List<Point> to collect the positions and creates and starts a Timer along with lambda code to do the recoding in the Timer.Tick event:
private void btn_Record_Click(object sender, EventArgs e)
{
points = new List<Point>();
index = 0;
tt = new Timer()
{ Interval = 50, Enabled = true };
tt.Tick += (ss, ee) =>
{
if (!points.Any() || points.Last() != Control.MousePosition)
points.Add(Control.MousePosition);
};
}
Next a button to stop recording:
private void btn_Stop_Click(object sender, EventArgs e)
{
if (tt!=null) tt.Stop();
}
Finally the replay button; it uses an index to loop over the the points collection in a new Timer.Tick code but using the same timer:
private void btn_Replay_Click(object sender, EventArgs e)
{
index = 0;
tt = new Timer() { Interval = 50, Enabled = true };
tt.Tick += (ss, ee) =>
{
if (index < points.Count)
{ System.Windows.Forms.Cursor.Position = points[index++]; }
else tt.Stop();
}
A few notes:
As asked in the question this will record and reply the Mmouse coodinates. It will do so in fixed intervals, so playback will look very similar to the original movements; in fact it is so hard to tell apart that I added a slowmo button with a longer interval to demonstrate.. (But the gif got too large)
The code will record the mouse positions in screen coordinates and should capture them wherever it goes, not only inside your application. See how VS is activating the code loupe!
It will not record any other mouse events, like up, down, click, doubleclick or wheel. For those you would need a global mouse hook for capturing and some external calls for replaying.
For including other mouse events you would also need a different and extended data structure; and you would also have to go from a timer-driven model to a mouse event driven one.
The example uses buttons to start and stop. Of course the movenments to and from those buttons get included in the recorded list of positions. Instead one could use a timed start, which would start recording after a few seconds and stop recording after a few seconds of inactivity..
There are various ways you can save and load the points; the simplest one is to serialize to xml; using a string path = #"..." it could look as simple as this:
private void btn_save_Click(object sender, EventArgs e)
{
if (points == null) points = new List<Point>();
XmlSerializer xs = new XmlSerializer((points).GetType());
using (TextReader tr = new StreamReader(path))
{
points = (List<Point>)xs.Deserialize(tr);
tr.Close();
}
}
private void btn_load_Click(object sender, EventArgs e)
{
XmlSerializer xs = new XmlSerializer((points).GetType());
using (TextWriter tw = new StreamWriter(path))
{
xs.Serialize(tw, points);
tw.Close();
}
}
Other ways would be using a binary formatter or a custom conversion routine. Xml is relatively stable.
Here is a short clip:
Related
I've managed to open a txt file to a ComboBox where it shown only the second element"100", and if I select one of the items in ComboBox will show me the the first element witch is "firstName", the problem is I want to modify the first element from the textbox and save it to the main file or new file on the way that I replace the old element with new one from the textbox and save the file as it was at the beginning
TXT FILE
firstName;;;100;;;0;
firstName;;;100;;;1;
firstName;;;100;;;2;
firstName;;;100;;;3;
firstName;;;0100;;;4;
firstName;;;0100;;;5;
firstName;;;0100;;;6;
firstName;;;0100;;;7;
lastName;;;0100;;;0;
lastName;;;0100;;;1;
lastName;;;0100;;;2;
lastName;;;0100;;;3;
lastName;;;0100;;;4;
lastName;;;0100;;;5;
lastName;;;0100;;;6;
lastName;;;0100;;;7;
i want to change the first elements from the textbox and replace it with user input and save the file as in it were,
example:
//output
john;;;100;;;0;
Patrick;;;100;;;1;
firstName;;;100;;;2;
namespace WindowsFormsApp8
{
public partial class Form1 : Form
{
public string[] lines;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.FilterIndex = 2;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
//string[] lines = File.ReadAllLines(openFileDialog.FileName);
lines = File.ReadAllLines(openFileDialog.FileName);
List<string> result = new List<string>();
string[] par = new string[1];
par[0] = ";;;";
for (int i = 0; i < lines.Length; i++)
{
string[] row = lines[i].Split(par, StringSplitOptions.None);
if (row.Length > 2)
{
if (!result.Contains(row[1]))
result.Add(row[1]);
}
}
foreach (string line in result)
{
comboBox1.Items.Add(line);
}
}
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var d = lines;
var t = d.Where(g => g.Contains(comboBox1.Text));
string allItems = "";
foreach (string item in t)
{
string[] r = item.Split(new string[] { ";;;" }, StringSplitOptions.None);
allItems += r[0] + Environment.NewLine;
}
textBox1.Text = allItems;
}
}
}
I've read your code carefully and my understanding may not be perfect but it should be close enough that I can help. One way to achieve your objectives is with data binding and I'll demonstrate this step by step.
"open a txt file to a combobox"
In your main form, you'll move the OpenFileDialog so that it is now a member variable:
private OpenFileDialog openFileDialog = new OpenFileDialog
{
InitialDirectory = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Files"),
FileName = "Data.txt",
Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*",
FilterIndex = 2,
RestoreDirectory = true,
};
In the main form CTor
Handle event buttonLoad.Click to display the dialog
Handle event openFileDialog.FileOk to read the file.
The DataSource of comboBox will be set to the list of lines read from the file.
Initialize
public MainForm()
{
InitializeComponent();
buttonLoad.Click += onClickLoad;
openFileDialog.FileOk += onFileOK;
comboBox.DataSource = lines;
.
.
.
Disposed += (sender, e) => openFileDialog.Dispose();
}
BindingList<Line> lines = new BindingList<Line>();
private void onClickLoad(object? sender, EventArgs e) =>
openFileDialog.ShowDialog();
In a minute, we'll look at those three things step by step. But first...
Serialize and Deserialize
You have a lot of loose code doing string splits to decode your serializer format. Try consolidating this in a class that is also suitable to be used in a BindingList<Line>. This will be the data source of your combo box. Also consider using a standard serialization format like JSON instead!
class Line : INotifyPropertyChanged
{
// Make a Line from serialized like firstName;;;100;;;0;
public Line(string serialized)
{
// Convert to a stored array
_deserialized = serialized.Split(new string[] { ";;;" }, StringSplitOptions.None);
}
// Convert back to the format used in your file.
public string Serialized => string.Join(";;;", _deserialized);
private string[] _deserialized { get; } // Backing store.
// Convert a list of Lines to a collection of strings (e.g. for Save).
public static IEnumerable<string> ToAllLines(IEnumerable<Line> lines) =>
lines.Select(_ => _.Serialized);
// Determine how a Line will be displayed in the combo box (e.g. "0100").
public override string ToString() => _deserialized[1].ToString();
// Use array syntax to access elements of the split array.
public string this[int index]
{
get => _deserialized[index];
set
{
if(!Equals(_deserialized[index],value))
{
// Send event when any array value changes.
_deserialized[index] = value;
OnPropertyChanged($"{index}");
}
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Load
Once the data file is selected, the raw text file will be shown and the combo box will be populated.
private void onFileOK(object? sender, CancelEventArgs e)
{
lines.Clear();
foreach (var serialized in File.ReadAllLines(openFileDialog.FileName))
{
lines.Add(new Line(serialized));
}
textBoxMultiline.Lines = lines.Select(_=>_.Serialized).ToArray();
comboBox.SelectedIndex = -1;
}
Replacement
Going back to the main form CTor there are three more events we care about:
public MainForm()
{
.
.
.
comboBox.SelectedIndexChanged += onComboBoxSelectedIndexChanged;
textBoxEditor.TextChanged += onEditorTextChanged;
lines.ListChanged += onListChanged;
.
.
.
}
When a new item is selected in the combo box, put it in the text editor.
private void onComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
var item = (Line)comboBox.SelectedItem;
if (item != null)
{
textBoxEditor.Text = item[0];
}
}
When the textEditor text changes, modify the item.
private void onEditorTextChanged(object? sender, EventArgs e)
{
var item = (Line)comboBox.SelectedItem;
if (item != null)
{
item[0] = textBoxEditor.Text;
}
}
When the item changes, update the file display in the big textbox.
private void onListChanged(object? sender, ListChangedEventArgs e)
{
switch (e.ListChangedType)
{
case ListChangedType.ItemChanged:
textBoxMultiline.Lines = lines.Select(_=>_.Serialized).ToArray();
break;
}
}
Save
SaveFileDialog saveFileDialog = new SaveFileDialog
{
InitialDirectory = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Files"),
FileName = "Data.txt",
Filter = "txt file (*.txt)|*.txt|All files (*.*)|*.*",
FilterIndex = 2,
RestoreDirectory = true,
};
private void onClickSave(object? sender, EventArgs e) =>
saveFileDialog.ShowDialog(this);
private void onSaveFileOK(object? sender, CancelEventArgs e)
{
File.WriteAllLines(saveFileDialog.FileName, Line.ToAllLines(lines));
}
I hope this is "close enough" to what you have described that if will give you some ideas to experiment with.
Create an object in the class "Series ema = new Series("ema");"
With the button "indicator_Click" download modal dialog.
In the window using the "ComboBox" select options: dig.type, dig.period.
Series ema = new Series("ema");
**********************************************
private void indicator_Click(object sender, EventArgs e)
{
ModalDialogBox dig = new ModalDialogBox();
{
if (dig.ShowDialog() == DialogResult.OK)
{
string formulaName = dig.type;
FinancialFormula formula = (FinancialFormula)Enum.Parse(typeof(FinancialFormula), formulaName, true);
chart1.Series.Add(ema);
chart1.DataManipulator.FinancialFormula(formula, dig.period, "price", "ema");
chart1.Series["ema"].Color = Color.Red;
chart1.Series["ema"].ChartType = SeriesChartType.Line;
chart1.Series["ema"].BorderWidth = 2;
chart1.Series["ema"].ShadowOffset = 1;
}
}
}
Next, if the indicator is not needed, delete it.
private void delete_Click(object sender, EventArgs e)
{
chart1.Series.Remove(ema);
}
I need to be able to add a second, third indicator.
If I try to add a series of the second indicator, an error occurs because the indicator already exists.
You can of course create multiple objects in a class:
Series ema1 = new Series("ema1");
Series ema2 = new Series("ema2");
Series ema3 = new Series("ema3");
but I do not like this method, because I do not know in advance how many indicators will be needed
I'm still confused whats better to use, datagridview or Be.HexEditor,
I am pretty sure I'll be able to do it with datagridview, but I like be.hex more, especially speed, UI etc...
But I tried to understand the code of be.hex, and I can't figure out how does it work, and also is it possible to show values from bytes arrays to the HexBox(not only from opening .bin files). it also uses dynamicFileByteProvider, and there is no info on the net about this class.
dynamicFileByteProvider = new DynamicFileByteProvider(fileName);
dynamicFileByteProvider.Changed += new EventHandler(byteProvider_Changed);
dynamicFileByteProvider.LengthChanged += new EventHandler(byteProvider_LengthChanged);
my app will open 1024 bytes files max, and also it will read bytes from comm port
I've tinkered a bit with this. What I did was
1) put an invisible picture box as control placeholder on the form, here named ph1
2) configure the HexBox control in Form_Load()
private HexBox hexBox;
private void Form1_Load(object sender, EventArgs e)
{
hexBox = new HexBox()
{
Top = ph1.Top,
Width = ph1.Width,
Height = ph1.Height,
Left = ph1.Left,
Visible = true,
UseFixedBytesPerLine = true,
BytesPerLine = 16,
ColumnInfoVisible = true,
LineInfoVisible = true,
StringViewVisible = true,
VScrollBarVisible = true
};
this.Controls.Add(hexBox);
this.Controls.Remove(ph1);
}
3) Load the actual file in DragDrop event
var filePath = ((string[])(e.Data.GetData(DataFormats.FileDrop)))[0];
var source = new FileByteProvider(filePath);
hexBox.ByteProvider = source;
hexBox.Refresh();
Example after drag/drop of a docx file onto the form:
Edit: if you wish to provide some self-generated array of bytes, it is as simple as this:
byte[] byteArr = {0xaa, 0x3f, 0x4b};
hexBox.ByteProvider = new DynamicByteProvider(byteArr);
Edit 2: To save the contents of the hex box:
I am sure there is some better way to do this. What I found for now is to simply add a handler in the hex box definition block:
hexBox.CopiedHex += HexBox_CopiedHex;
Have some kind of "save" button with such a code:
private void button1_Click(object sender, EventArgs e)
{
hexBox.SelectAll();
hexBox.CopyHex();
hexBox.SelectionLength = 0;
}
And such an event handler:
private void HexBox_CopiedHex(object sender, EventArgs e)
{
var hex = Clipboard.GetText();
var hexHex = hex.Split(' ');
var hexArr = new byte[hexHex.Length];
for (var i = 0; i < hexHex.Length; i++)
{
hexArr[i] = byte.Parse(hexHex[i], NumberStyles.AllowHexSpecifier);
}
File.WriteAllBytes(#"C:\00_Work\test.bin", hexArr);
}
To show byte[] in hexbox use new DynamicByteProvider(byte[]
To get modified byte[] from hexbox
use DynamicByteProvider.Bytes.ToArray()
UI for browsing data
Im lookig for a way to save and open multiple entries of data from the text boxes onto a .txt file. By "multiple entries" I mean having a kind of database of (in this instance) members of a certain team, without the use of LINQ. So for example having Messi and his data as the first entry, then when I press "Next", the second player would appear along with their data.
Currently I am using the SaveFileDialog and OpenFileDialog method to save and open entries, however it only saves a single record.
private void menu_save_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == true)
{
using (StreamWriter write = new StreamWriter(File.Create(sfd.FileName)))
{
write.WriteLine(tbox_name.Text);
write.WriteLine(tbox_dob.Text);
write.WriteLine(tbox_number.Text);
write.WriteLine(tbox_nationality.Text);
write.WriteLine(tbox_height.Text);
write.WriteLine(tbox_weight.Text);
write.WriteLine(tbox_position.Text);
write.Close();
write.Dispose();
}
}
}
private void menu_open_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
using (StreamReader read = new StreamReader(File.OpenRead(ofd.FileName)))
{
tbox_name.Text = read.ReadLine();
tbox_dob.Text = read.ReadLine();
tbox_number.Text = read.ReadLine();
tbox_nationality.Text = read.ReadLine();
tbox_height.Text = read.ReadLine();
tbox_weight.Text = read.ReadLine();
tbox_position.Text = read.ReadLine();
read.Close();
read.Dispose();
}
}
}
.txt file after saving data
I would like the application to be able to save, for example, 11 entries (players) on a single .txt file and be able to go through the "database" with the 'Next' and 'Previous' buttons. I would also like to have an option to sort the players in an alphabetical order. Any help would be much appreciated as Im new to WPF and havent quite gotten my head around it yet.
File.Create overwrites existing file (all previous data gets lost). Use File.AppendAllLines method:
private void menu_save_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == true)
{
File.AppendAllLines(sfd.FileName, new string []
{
tbox_name.Text,
tbox_dob.Text,
tbox_number.Text,
tbox_nationality.Text,
tbox_height.Text,
tbox_weight.Text,
tbox_position.Text,
});
}
}
similarly to read all data use File.ReadAllLines method, but you will have to separate lines into groups after that:
string[] lines;
int index;
private void menu_open_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == true)
{
lines = File.ReadAllLines(ofd.FileName);
index = 0;
Display(index);
}
}
private void Display(int number)
{
int i = number * 7; // 7 is a number of values per item
tbox_name.Text = lines[i];
tbox_dob.Text = lines[i+1];
tbox_number.Text = lines[i+2];
tbox_nationality.Text = lines[i+3];
tbox_height.Text = lines[i+4];
tbox_weight.Text = lines[i+5];
tbox_position.Text = lines[i+6];
}
to display next, do index++; Display(index);
to display previous, do index--; Display(index);
In form1 I created simple form called formhaslo.
I created in formhaslo control called listBoxhaslo
Now, I want to create MouseDoubleClick Event to listBoxhaslo.
I have problem with getting listBoxhaslo from formhaslo to form1.
Can you take a look at this code, please (check out comments):
public partial class Form1 : Form
{
Form formhaslo = new Form();
...
...
...
public void buttonLoadPassForBAKFile_Click(object sender, EventArgs e)
{
int i = 0;
string path = #"Backups";
formhaslo.StartPosition = FormStartPosition.CenterScreen;
ListBox listBoxhaslo = new ListBox();
listBoxhaslo.Location = new System.Drawing.Point(0, 30);
listBoxhaslo.Left = (formhaslo.ClientSize.Width - listBoxhaslo.Width) / 2;
using (FileStream fsSbHaslo = new FileStream(path + #"\BAKPass._pass", FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (StreamReader srhaslo = new StreamReader(fsSbHaslo, Encoding.Default))
{
string line;
while ((line = srhaslo.ReadLine()) != null)
{
listBoxhaslo.Items.Add(line);
i++;
}
srhaslo.Close();
}
formhaslo.Controls.Add(listBoxhaslo);
formhaslo.Controls.Add(label1);
listBoxhaslo.MouseDoubleClick += new MouseEventHandler(listBoxhaslo_MouseDoubleClick); // <---here is EventHandler
formhaslo.Show();
}
}
void listBoxhaslo_MouseDoubleClick(object sender, MouseEventArgs e)
{
if ((listBoxhaslo.SelectedItem) != null) // <--listBoxhaslo does not exist in current context
{
PassForBakFile = (listBoxhaslo.SelectedItem.ToString());
formhaslo.Hide();
}
}
I know that this error must be there because im doing it wrong but I don't know how to do it.
The listBoxhaslo doesn't exists because it was declare within the scope of first function which is not visible to the second function of your event listBoxhaslo_MouseDoubleClick. For you to make it work you need to declare listBoxhaslo variable outside of your function. You could declare it after formhaslo near top. Or another way to accomplish this is to cast sender to ListBox within your event.
void listBoxhaslo_MouseDoubleClick(object sender, MouseEventArgs e)
{
var listBoxhaslo = (sender as ListBox);
if (listBoxhaslo.SelectedItem != null)
{
PassForBakFile = (listBoxhaslo.SelectedItem.ToString());
formhaslo.Hide();
}
}
I haven't tried the code but I think it will do.