How can I modify what gets copied to the Clipboard? - c#

I'm copying a DataGrid to the clipboard so that it can be pasted to e.g. Excel while maintaining its format like this:
MyDataGrid.SelectAllCells();
MyDataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, MyDataGrid);
This works very nice. However, I need to add the string "MyDataGridTitle". If pasted to Excel, this should simply stand above the DataGrid.
I have tried various ways (e.g. use a DataObject) and tortured google, but to no success. I'd be thankful for a hint, tip or answer!

This is not a very elegant solution, but you can try by manipulating the html string generated by your DataGrid (indeed when you paste in Excel, the DataFormats.Html format is the one which is used).
Something like this:
dg.SelectAllCells();
dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, dg);
string dataGridContent = (string)Clipboard.GetData(DataFormats.Html);
dataGridContent = dataGridContent.Replace("<TABLE>",
String.Format("<TABLE><TR><TD colspan='{0}'>Your additional text<TD></TR>", dg.Columns.Count));
Clipboard.SetText(dataGridContent, TextDataFormat.Html);
Of course you can improve this code for example by using regular expressions instead of the Replace method.

Related

Change csv delimiter for Clipobard.GetData()

I try to save a datagrid as csv via copy datagrid to clipboard acording to this post:
Copy text from WPF DataGrid to Clipboard to Excel
The export works, but the column delimiter is "," but I use a german region setting with ";" delimiter character. The hole text is in one column:(
Can I change the DataFormats.CommaSeparatedValue delimiter?
Thank you and have a nice day
Chris
Not sure if you can change the delimiter. If you don't find a way, you can always do this:
string result1 = ((string)Clipboard.GetData(DataFormats.CommaSeparatedValue)).Replace(";",",");
From what I can tell, you can't change it.
I would agree with what someone already said in your link - you shouldn't be saving csv data to an xls file. When you open a .csv file with excel, it will ask you what delimiter you want to use before you import it.
If you want to change your delimiter before saving, take a look at this post.
Make sure to also take a look at the link in that answer - you'd need to use the Microsoft.VisualBasic.FileIO namespace.
However, if you still decide to save as .xls, be careful - you might change your delimiter to ';' before saving, but people whose excel expects ',' as a delimiter will have the same problem you have now.
i solved to problem by save the DataTable instead the DataGrid. The DataTableExtensions class in the link below works very well.
c# datatable to csv
Thanks

RichTextBox inserting text

For Windows Forms.
I am trying to insert text into the .rtf field of a RichTextBox.
I have tried two methods. When I use .Rtf.insert, nothing happens at all.
When I edit the .rtf string based on the selected text positions myself, I either end up adding gibberish to the thing or getting an error that says that the file format is invalid. My best guess is that this is because the .rtf string is in .rtf format and the selection index that I am using is based on the plain text string and so I am inserting the text in the wrong location in the .rtf string and messing up the RTF code.
But knowing what the problem is (if I am correct) hasn't helped me solve it.
Is there a way to get .rtf.insert to work correctly, or is there a way to translate the selected text indexes to the actual .rtf text positions so that something like the code below would work? I am assuming that the RichTextBox itself must know how to translate the one index into another because it can insert characters when the user types just fine.
Here is my code snippet. The point of the code is to insert a marker into the text that will later be parsed and replaced with a student's first name. There will be other such codes. "codeLeader" and "codeEnder" are just the strings I use to surround the codes with. In this case I am using "[*" and *]" to indicate that there is a code I will need to parse, but I put them into separate strings so that I can easily change it if I wish. I have actually already written the parsing code, which works just fine on rich text. It is just inserting the text into the richTextBox itself that is the problem. In other words, if I were to type the codes by hand it would work just fine. But this would be troublesome for the user because some of the codes will use index numbers.
private void studentFirstNameCode_Click(object sender, EventArgs e)
{
string ins = f1ref.codeLeader;
ins += "SNFirst" + f1ref.codeEnder;
int start = editorField.richTextBox1.SelectionStart;
if (start == -1) { start = 0; }
int end = start + editorField.richTextBox1.SelectionLength;
if (end == -1) { end = 0; }
string pre = editorField.richTextBox1.Rtf.Substring(0, start);
string post = editorField.richTextBox1.Rtf.Substring(end);
string newstring = pre + ins + post;
editorField.richTextBox1.Rtf = newstring;
// this also doesn't work. gives no result at all.
// editorField.richTextBox1.Rtf.Insert(start, newstring);
}
I don't think that you need to use the RTF property to simple insert a text inside the RichTextBox actual text. In particular because you don't seem to add an RTF formatted text.
If you don't want to use RTF then the simplest way to accomplish your goal is just one line of code
editorField.SelectedText = yourParameterText;
This will work as you have pasted the text from the clipboard in the selected position (eventually replacing text if something is selected) and the base work of correctly formatting your text inside the RTF is done by the control itself
I have found a work-around by using .SendKeys. This makes the text appear a bit slowly (as if typed very quickly) so isn't optimal, but it does work.
It is enough for a workable solution, but I am still troubled by the problem. It seems like this issue should have a more elegant solution than this.

Inserting a Line at a specific place in a txt using .net

The process I currently use to insert a string into a text file is to read the file and modify it as I write the file out again which seems to be how everyone is doing it.
Since .net has such a diverse library I was wondering if there was a specific command for inserting a string at a specific line in a txt file.
I would imagine it would look something like this:
dim file as file
file.open("filePath")
file.insert(string, location) 'this isn't actually an option, I tried
No, there's nothing specifically to do that in .NET.
You can do it very simply if you're happy to read all the lines of text in:
var lines = File.ReadAllLines("file.txt").ToList();
lines.Insert(location, text);
File.WriteAllLines("file.txt", lines);
It would be more efficient in terms of memory to write code to copy a line at a time, inserting the new line at the right point while you copy, but that would be more work. If you know your file will be small, I'd go for the above.
You could simply read all the text into a string, then use the string insert method, e.g.
File.WriteAllText("file.txt", File.ReadAllText("file.txt").Insert(startIndex, "value"));

Get cell style from excel spreadsheet with C#

Im trying to copy some cells from one workbook-sheet to another workbook-sheet and preserve the style and formatting using C#.
I can get the attributes one by one like this:
string fontName = ((Excel.Range) workSheet.Cells[3, 2]).Font.Name.ToString();
But Im looking for at way to get it all at once. Thanks
If you copy the cell(s) via the clipboard using the Range.Copy Destination:= method then both the content and formatting will be copied. If you just want to copy the formatting use .Copy and then .PasteSpecial formats

Read fixed width record from text file

I've got a text file full of records where each field in each record is a fixed width. My first approach would be to parse each record simply using string.Substring(). Is there a better way?
For example, the format could be described as:
<Field1(8)><Field2(16)><Field3(12)>
And an example file with two records could look like:
SomeData0000000000123456SomeMoreData
Data2 0000000000555555MoreData
I just want to make sure I'm not overlooking a more elegant way than Substring().
Update: I ultimately went with a regex like Killersponge suggested:
private readonly Regex reLot = new Regex(REGEX_LOT, RegexOptions.Compiled);
const string REGEX_LOT = "^(?<Field1>.{6})" +
"(?<Field2>.{16})" +
"(?<Field3>.{12})";
I then use the following to access the fields:
Match match = reLot.Match(record);
string field1 = match.Groups["Field1"].Value;
Use FileHelpers.
Example:
[FixedLengthRecord()]
public class MyData
{
[FieldFixedLength(8)]
public string someData;
[FieldFixedLength(16)]
public int SomeNumber;
[FieldFixedLength(12)]
[FieldTrim(TrimMode.Right)]
public string someMoreData;
}
Then, it's as simple as this:
var engine = new FileHelperEngine<MyData>();
// To Read Use:
var res = engine.ReadFile("FileIn.txt");
// To Write Use:
engine.WriteFile("FileOut.txt", res);
Substring sounds good to me. The only downside I can immediately think of is that it means copying the data each time, but I wouldn't worry about that until you prove it's a bottleneck. Substring is simple :)
You could use a regex to match a whole record at a time and capture the fields, but I think that would be overkill.
Why reinvent the wheel? Use .NET's TextFieldParser class per this how-to for Visual Basic: How to read from fixed-width text files.
You may have to watch out, if the end of the lines aren't padded out with spaces to fill the field, your substring won't work without a bit of fiddling to work out how much more of the line there is to read. This of course only applies to the last field :)
Unfortunately out of the box the CLR only provides Substring for this.
Someone over at CodeProject made a custom parser using attributes to define fields, you might wanna look at that.
Nope, Substring is fine. That's what it's for.
You could set up an ODBC data source for the fixed format file, and then access it as any other database table.
This has the added advantage that specific knowledge of the file format is not compiled into your code for that fateful day that someone decides to stick an extra field in the middle.

Categories