I am attempting to write a C# serial interface for a FPGA design I've implemented.
As part of the interface program I need to calculate a CRC-8 checksum.
I've attempted to do this on a low level(as that's the level I am more familiar with) but I am having issues.
The problem I am having is that assignments such as the ones on lines 91-95 (e.g. line 91: TempChecksumBits[7] = ChecksumBits[6];) are not only assigning the TempChecksumBits[] but is also changing the ChecksumBits[] value.
Any Ideas? Your help would be very much appreciated as I am less than familiar with high level languages.
Regards,
Mike
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
byte[] ReadBuffer = new byte[20];
ReadBuffer[0] = Convert.ToByte("10000001", 2);
ReadBuffer[1] = Convert.ToByte("00000000", 2);
ReadBuffer[2] = Convert.ToByte("11000011", 2);
ReadBuffer[3] = Convert.ToByte("00001111", 2);
ReadBuffer[4] = Convert.ToByte("01010101", 2);
ReadBuffer[5] = Convert.ToByte("00001111", 2);
ReadBuffer[6] = Convert.ToByte("01010101", 2);
ReadBuffer[7] = Convert.ToByte("00001111", 2);
ReadBuffer[8] = Convert.ToByte("01010101", 2);
ReadBuffer[9] = Convert.ToByte("00001111", 2);
ReadBuffer[10] = Convert.ToByte("01010101", 2);
ReadBuffer[11] = Convert.ToByte("00001111", 2);
ReadBuffer[12] = Convert.ToByte("01010101", 2);
ReadBuffer[13] = Convert.ToByte("00001111", 2);
ReadBuffer[14] = Convert.ToByte("01010101", 2);
ReadBuffer[15] = Convert.ToByte("00001111", 2);
ReadBuffer[16] = Convert.ToByte("01010101", 2);
ReadBuffer[17] = Convert.ToByte("00001111", 2);
ReadBuffer[18] = Convert.ToByte("01010101", 2);
ReadBuffer[19] = Convert.ToByte("11100111", 2);
CheckDataPacket(ReadBuffer);
}
private void CheckDataPacket(byte[] ReadBuffer)
{
byte[] Checksum = new byte[1];
Checksum[0] = Convert.ToByte("00000000", 2);
byte[] DataBytes = new byte[18];
DataBytes[0] = ReadBuffer[2];
DataBytes[1] = ReadBuffer[3];
DataBytes[2] = ReadBuffer[4];
DataBytes[3] = ReadBuffer[5];
DataBytes[4] = ReadBuffer[6];
DataBytes[5] = ReadBuffer[7];
DataBytes[6] = ReadBuffer[8];
DataBytes[7] = ReadBuffer[9];
DataBytes[8] = ReadBuffer[10];
DataBytes[9] = ReadBuffer[11];
DataBytes[10] = ReadBuffer[12];
DataBytes[11] = ReadBuffer[13];
DataBytes[12] = ReadBuffer[14];
DataBytes[13] = ReadBuffer[15];
DataBytes[14] = ReadBuffer[16];
DataBytes[15] = ReadBuffer[17];
DataBytes[16] = ReadBuffer[18];
DataBytes[17] = ReadBuffer[1];
CalculateChecksum(DataBytes, ref Checksum);
textBox1.Text = (Convert.ToString(Checksum[0]));
}
private void CalculateChecksum(byte[] DataBytes, ref byte[] Checksum)
{
BitArray ChecksumBits = new BitArray(Checksum);
BitArray TempChecksumBits = new BitArray(Checksum);
for (int i = 0; i < 18; i++)
{
byte[] CurrentByte = new byte[1];
CurrentByte[0] = DataBytes[i];
BitArray DataBits = new BitArray(CurrentByte);
for (int k = 0; k < 8; k++)
{
TempChecksumBits[7] = ChecksumBits[6];
TempChecksumBits[6] = ChecksumBits[5];
TempChecksumBits[5] = ChecksumBits[4];
TempChecksumBits[4] = ChecksumBits[3];
TempChecksumBits[3] = ChecksumBits[2];
if ((ChecksumBits[7]) == (ChecksumBits[1]))
{
TempChecksumBits[2] = false;
}
else
{
TempChecksumBits[2] = true;
}
if ((ChecksumBits[7]) == (ChecksumBits[0]))
{
TempChecksumBits[1] = false;
}
else
{
TempChecksumBits[1] = true;
}
if ((DataBits[7-k]) == (ChecksumBits[7]))
{
TempChecksumBits[0] = false;
}
else
{
TempChecksumBits[0] = true;
}
ChecksumBits = TempChecksumBits;
}
}
/////////////// re-form checksum Byte/////////////////////
for (int j = 0; j < 8; j++)
{
if (ChecksumBits[j] == true)
{
double Value = Math.Pow(2, j);
Checksum[0] += (byte)(Value);
}
}
}
}
}
This line is the problem, just at the end of all your if/else blocks:
ChecksumBits = TempChecksumBits;
After that, the two variables refer to the same instance of BitArray. It's not clear why you're doing that or what you were trying to achieve, but it's clearly not doing what you really wanted.
Note that all the blocks like this:
if ((ChecksumBits[7]) == (ChecksumBits[1]))
{
TempChecksumBits[2] = false;
}
else
{
TempChecksumBits[2] = true;
}
can be simplified to:
TempChecksumBits[2] = ChecksumBits[7] != ChecksumBits[1];
... which will make your code much simpler.
(I'd also strongly advise you to name your local variables using camelCase rather than PascalCase.)
To be honest, I'd be tempted to use just a byte and bit-shifting/swapping techniques rather than all the BitArray objects...
Related
How to iterate through all ToolStripMenuItem in a MenuStrip
con.connection3.Open();
string query = "SELECT * FROM tblrole WHERE role = ?role";
using (MySqlCommand cmd3 = new MySqlCommand(query,con.connection3))
{
cmd3.Parameters.AddWithValue("?role", roled);
using (MySqlDataReader mdr = cmd3.ExecuteReader())
{
while (mdr.Read())
{
for (int o = 0, i = 2; o < fileMaintenanceToolStripMenuItem.DropDownItems.Count; o++, i++)
{
fileMaintenanceToolStripMenuItem.DropDownItems[o].Visible = mdr.GetBoolean(i);
}
for (int o = 0, i = 19; o < transactionToolStripMenuItem.DropDownItems.Count; o++, i++)
{
transactionToolStripMenuItem.DropDownItems[o].Visible = mdr.GetBoolean(i);
}
for (int o = 0, i = 45; o < reportsToolStripMenuItem.DropDownItems.Count; o++, i++)
{
reportsToolStripMenuItem.DropDownItems[o].Visible = mdr.GetBoolean(i);
}
for (int o = 0, i = 55; o < utilitiesToolStripMenuItem.DropDownItems.Count; o++, i++)
{
utilitiesToolStripMenuItem.DropDownItems[o].Visible = mdr.GetBoolean(i);
}
if (!fileMaintenanceToolStripMenuItem.HasDropDownItems)fileMaintenanceToolStripMenuItem.Visible = false;
else fileMaintenanceToolStripMenuItem.Visible = true;
if (!transactionToolStripMenuItem.HasDropDownItems)transactionToolStripMenuItem.Visible = false;
else transactionToolStripMenuItem.Visible = true;
if (!reportsToolStripMenuItem.HasDropDownItems)reportsToolStripMenuItem.Visible = false;
else reportsToolStripMenuItem.Visible = true;
if (!utilitiesToolStripMenuItem.HasDropDownItems) utilitiesToolStripMenuItem.Visible = false;
else utilitiesToolStripMenuItem.Visible = true;
}
}
}
con.connection3.Close();
Works fine if the ToolStripMenuItem has no subitems but I need to iterate through them also
You can use a recursive method as a good option for traversing a tree structure. Here is an extension method that you can use for listing ToolStripMenuItem descendants of a given ToolStripMenuItem:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
public static class ToolStripMenuItemExtensions
{
public static List<ToolStripMenuItem> Descendants(this ToolStripMenuItem item)
{
var items = item.DropDownItems.OfType<ToolStripMenuItem>().ToList();
return items.SelectMany(x => Descendants(x)).Concat(items).ToList();
}
}
It will add Descendants to ToolStripMenuItem elements, so you can use it this way:
var allMenuItems = fileMaintenanceToolStripMenuItem.Descendants();
Hello I have a code where I inside of a datagridview generate buttons with data from sql server database. But now I want to scroll them through buttons. I tried lots of things all gives me error already saw a post about this but nothing worked for me can someone help.
<-----------------------------------My code------------------------------------->
Methods to fill the datagridview:
public void TabelaFuncionario()
{
try
{
BDfuncionarios = new DataTable();
string cmd = "My select string";
var adpt = fConexao.GetDataAdapter(cmd);
BDfuncionarios.Clear();
adpt.Fill(BDfuncionarios);
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
public void BotaoFuncionario()
{
try
{
TabelaFuncionario();
PosXartigo = 1;
PosYartigo = 1;
//Apagar o painel todo
dataGridView1.Controls.Clear();
foreach (DataRow row in BDfuncionarios.Rows)
{
int posicaoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
if (posicaoX > maximoxArtigo)
{
PosYartigo++; PosXartigo = 1;
}
else
{
PosXartigo = PosXartigo != 1 ? PosXartigo++ : 1;
}
int PontoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
int PontoY = ((PosYartigo - 1) * Gap_Yartigo) + yInicial + (Altura_BotaoArtigo * (PosYartigo - 1));
Button bt1 = new Button();
bt1.Location = new Point(PontoX, PontoY);
Mo mo = new Mo();
mo.codmo = (int)row["Something"];
mo.nome_func = (string)row["Something"];
bt1.Name = "Botao" + NBotoes.ToString();
bt1.Height = Altura_BotaoArtigo;
bt1.Width = Largura_BotaoArtigo;
bt1.BackColor = Color.Tan;
bt1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
bt1.ForeColor = Color.Black;
bt1.Text = mo.nome_func;
bt1.Tag = mo;
bt1.FlatStyle = FlatStyle.Popup;
bt1.Click += btArtigo_click;
dataGridView1.Controls.Add(bt1);
NBotoes++;
PosXartigo++;
}
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
Image of my form (don't know if it helps):
http://imgur.com/f5G25nX
<--------------------------EDITED--------------------------------->
i have tried things like this :https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rowcount(v=vs.110).aspx
Gives me out of range or something like that
And tried this just now
int row = dataGridView1.RowCount;
MessageBox.Show(row+"");
And it displays me 0; how can i have buttons inside my grid but have 0 rows?
I solved the problem using this panel instead of datagrid for what u wanted it was much better the code will be below:
Methods:
public void TabelaFuncionario()
{
try
{
BDfuncionarios = new DataTable();
string cmd = "your select";
var adpt = fConexao.GetDataAdapter(cmd);
BDfuncionarios.Clear();
adpt.Fill(BDfuncionarios);
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
public void BotaoFuncionario()
{
try
{
TabelaFuncionario();
PosXartigo = 1;
PosYartigo = 1;
//Apagar o painel todo
panel2.Controls.Clear();
foreach (DataRow row in BDfuncionarios.Rows)
{
int posicaoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
if (posicaoX > maximoxArtigo)
{
PosYartigo++; PosXartigo = 1;
}
else
{
PosXartigo = PosXartigo != 1 ? PosXartigo++ : 1;
}
int PontoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
int PontoY = ((PosYartigo - 1) * Gap_Yartigo) + yInicial + (Altura_BotaoArtigo * (PosYartigo - 1));
Button bt1 = new Button();
bt1.Location = new Point(PontoX, PontoY);
Mo mo = new Mo();
mo.codmo = (int)row["Var1"];
mo.nome_func = (string)row["Var2"];
bt1.Name = "Botao" + NBotoes.ToString();
bt1.Height = Altura_BotaoArtigo;
bt1.Width = Largura_BotaoArtigo;
bt1.BackColor = Color.Tan;
bt1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
bt1.ForeColor = Color.Black;
bt1.Text = mo.nome_func;
bt1.Tag = mo;
bt1.FlatStyle = FlatStyle.Popup;
bt1.Click += btFuncionario_click;
panel2.Controls.Add(bt1);
NBotoes++;
PosXartigo++;
}
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
Now the PainelExtension class:
public static class PanelExtension
{
public static void ScrollDown(this Panel p, int pos)
{
//pos passed in should be positive
using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + pos })
{
p.ScrollControlIntoView(c);
}
}
public static void ScrollUp(this Panel p, int pos)
{
//pos passed in should be negative
using (Control c = new Control() { Parent = p, Height = 1, Top = pos })
{
p.ScrollControlIntoView(c);
}
}
}
The up and down button click:
private void upbt_Click(object sender, EventArgs e)
{
if (i >= 0) i = -1;
panel2.ScrollUp(i=i-30);
}
private void downbt_Click(object sender, EventArgs e)
{
if (i < 0) i = 0;
panel2.ScrollDown(i=i+20);
}
I got it to work like this maybe there were other ways to do it i choose this one.
I'm new to coding and am creating a windows form application in C#. I was having difficulties figuring out how to track the number of correct and incorrect responses. When a button is clicked, if the response is correct a label says correct. I want a different label to count the amount of times it says correct and incorrect. Here's what I was thinking but didn't work.
int add = 0;
add = int.Parse(correct.Text);
if (label1.Text == "Correct")
{
correct.Text = add++;
}
else
incorrect.text = add++;
correct and incorrect are names of my label.
Here's my button click event, there are many alike.
private void G_Click(object sender, EventArgs e)
{
if (go.Visible == true)
{
go.Visible = false;
Random rnd = new Random();
int y = rnd.Next(1, 7);
if (y == 1)
{
eo.Visible = true;
}
if (y == 2)
{
ao.Visible = true;
}
if (y == 4)
{
dd.Visible = true;
}
if (y == 5)
{
go.Visible = true;
}
if (y == 6)
{
eeo.Visible = true;
}
timer1.Start();
label1.Text = "Correct";
}
else
{
label1.Text = "Incorrect";
}
private int correctCount = 0;
private int incorrectCount = 0;
if (label1.Text = "Correct";)
{
correctCount++;
correct.Text = correctCount.ToString();
}
else
{
incorrectCount++;
incorrect.Text = incorrectCount.ToString();
}
The immediate problem is that the type of the Text property is string, not int - you have to set it to text, not a number. Fortunately, you can just call ToString on an int to get a string representation. However, I'd suggest there are other things to change too.
I would strongly suggest that you keep separate counters as variables. While you could keep parsing your labels, it's simpler for them to be purely output. So you might have:
// Fields
private int correctCount = 0;
private int incorrectCount = 0;
...
// Wherever your code is
if (correctAnswer)
{
correctCount++;
correct.Text = correctCount.ToString();
}
else
{
incorrectCount++;
incorrect.Text = incorrectCount.ToString();
}
Note the correctAnswer condition here - we don't know what's setting the text of label1, but I'd suggest that that's the right place to also change the correct/incorrect counters, from the same condition. Again, treat label1 just as output, rather than as a feedback system.
class fields = variables that are declared outside of a method and directly inside a class
local variables = variables that are declared inside of a method
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 deleteMe
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private int correctCount = 0; // field
private int incorrectCount = 0; // field
private void G_Click(object sender, EventArgs e)
{
if (go.Visible == true)
{
go.Visible = false;
Random rnd = new Random();
int y = rnd.Next(1, 7); // local variable
if (y == 1)
{
eo.Visible = true;
}
if (y == 2)
{
ao.Visible = true;
}
if (y == 4)
{
dd.Visible = true;
}
if (y == 5)
{
go.Visible = true;
}
if (y == 6)
{
eeo.Visible = true;
}
timer1.Start();
incorrect.Text = "Correct";
}
else
{
incorrect.Text = "Incorrect";
}
if (label1.Text = "Correct")
{
correctCount++;
correct.Text = correctCount.ToString();
}
else
{
incorrectCount++;
incorrect.Text = incorrectCount.ToString();
}
}
}
}
== equality. (for comparing 2 values)
= assign a value. (for initialize a variable or field)
I want to rename the specified worksheet and put some processed data on it, but the following code (which looks almost the same as every example I could find on this and other websites) just won't to what I want:
try
{
xl.Worksheet = (ExcelRefer.Worksheet) xl.Workbook.Worksheets.get_Item("Sheet1");
xl.Worksheet.Name = "Smoothed result";
xl.Workbook.Save();
xl.Range = xl.Worksheet.UsedRange;
Debug.WriteLine("Saved");
}
catch(Exception exception)
{
MessageBox.Show(exception.Message);
}
The exception is never thrown, so the code doesn't contain any errors but the worksheet in the document I've opened still has the same name. Also, the
Debug.WriteLine(...)
method is called and the output is correctly displayed. It does even ask me if I want to overwrite the existing file when I tell the Workbook to save. Could anyone tell me what I'm doing wrong?
Edit:
xl is an object of a class that contains all necessary elements for working with excel.
using ExcelRefer = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Tools.Excel;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ZedGraph;
class XLSXMulti
{
private static List<int[]> dataPositions = new List<int[]>();
private static PointPairList measureData = new PointPairList();
private static PointPairList[] dataComparison = new PointPairList[2];
private static bool smoothing = false;
private static bool measureDataFound = false;
private static bool fileFinished = false;
private static string[] excelFilePaths;
private static string[] temp;
private static int numberOfSamples;
private static BackgroundWorker[] bwg;
private static ProgressBar pbExcel;
public static void Init(string[] filePaths, ProgressBar pb, bool smooth)
{
excelFilePaths = filePaths;
pbExcel = pb;
smoothing = smooth;
measureData.Clear();
dataPositions.Clear();
temp = Interaction.InputBox("Number of consecutive values to be used " +
"for smoothing and the iteration step. These values" +
" will be used for all selected files.\n" +
"IMPORTANT: The two values have to be separated with a ','!",
"Select grade of smoothing",
"5,1", 500, 480).Split(',');
bwg = new BackgroundWorker[Environment.ProcessorCount];
for(int i = 0; i < bwg.Length; i ++)
{
bwg[i] = new BackgroundWorker();
}
foreach(BackgroundWorker bw in bwg)
{
bw.DoWork += bwg_doWork;
bw.ProgressChanged += bwg_ProgressChanged;
bw.RunWorkerCompleted += bwg_RunworkerCompleted;
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
}
List<string>[] filesForWorkers = new List<string>[bwg.Length];
for(int i = 0; i < filesForWorkers.Length; i ++)
{
filesForWorkers[i] = new List<string>();
}
int filesPerWorker = filePaths.Length / bwg.Length;
int workerindex = 0;
MessageBox.Show("filesPerWorker: " + filesPerWorker + "\n" +
"filePaths: " + filePaths.Length + "\n" +
"bwg: " + bwg.Length);
for(int i = 0; i < filePaths.Length; i ++)
{
filesForWorkers[workerindex].Add(filePaths[i]);
workerindex ++;
if(workerindex == bwg.Length)
{
workerindex = 0;
}
}
for(int i = 0; i < bwg.Length; i ++)
{
bwg[i].RunWorkerAsync(filesForWorkers[i]);
}
}
private static void bwg_doWork(object sender, DoWorkEventArgs e)
{
List<string> filelist = e.Argument as List<string>;
Excelattributes xl = new Excelattributes();
foreach(string s in filelist)
{
try
{
xl.App = new ExcelRefer.Application();
xl.Workbook = xl.App.Workbooks.Open(s, 0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xl.Worksheet = (ExcelRefer.Worksheet)xl.Workbook.Worksheets.get_Item(1); // Zugriff auf eingegebenes Tabellenblatt
xl.Range = xl.Worksheet.UsedRange;
findMeasureData(xl);
if(xl.Workbook != null){xl.Workbook.Close(true, null, null);}
if(xl.App != null) {xl.App.Quit();}
}
catch(Exception exception)
{
MessageBox.Show(exception.Message, "Exception");
}
finally
{
if(xl.Workbook != null){xl.Workbook.Close(true, null, null);}
if(xl.App != null) {xl.App.Quit();}
}
}
}
private static void bwg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// TODO: implement some sort of progress reporting
}
private static void bwg_RunworkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Statuslabel.label.Text = "Backgroundworker finished";
(sender as BackgroundWorker).Dispose();
}
private static void findMeasureData(Excelattributes xl)
{
// Erste 15 Zeilen durchgehen, um herauszufinden wo die Messwerte beginnen (9 + 6 Sicherheit)
// Nur bis inkl. Spalte AZ
try
{
for(int zeile = 1; zeile <= 15; zeile ++)
{
for(int spalte = 1; spalte <= 52; spalte ++)
{
// WICHTIG: (xl.Range...).Text verwenden, um Nullreferenceexception zu vermeiden [?]
Object zelleninhalt = (xl.Range.Cells[zeile, spalte] as ExcelRefer.Range).Text;
if(zelleninhalt.Equals("DATA START"))
{
dataPositions.Add(new int[2] {zeile +1, spalte +1});
measureDataFound = true;
}
else if(zelleninhalt.Equals("Number of Samples"))
{
numberOfSamples = Convert.ToInt32((xl.Range.Cells[zeile, spalte+1] as
ExcelRefer.Range).Text);
}
}
}
if(measureDataFound == true)
{
int[,] temp = new int[dataPositions.Count, 2];
for(int i = 0; i < dataPositions.Count; i ++)
{
temp[i, 0] = dataPositions.ElementAt(i).ToArray()[0];
temp[i, 1] = dataPositions.ElementAt(i).ToArray()[1];
}
readMeasureData(temp, xl);
}
}
catch(Exception exception)
{
MessageBox.Show(exception.Message, "Exception");
}
}
private static void readMeasureData(int[,] temp, Excelattributes xl)
{
int[,] zellen = temp;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
for(int i = zellen[0,0]; i < (zellen[0,0] + numberOfSamples); i ++)
{
try
{
double weg = Convert.ToDouble((xl.Range.Cells[i, zellen[0,1]] as ExcelRefer.Range).Value2);
double kraft = Convert.ToDouble((xl.Range.Cells[i, zellen[1,1]] as ExcelRefer.Range).Value2);
measureData.Add(new PointPair(weg, kraft));
}
catch(Exception exception)
{
MessageBox.Show(exception.Message, "Exception");
Application.Exit();
}
}
stopwatch.Stop();
MessageBox.Show(stopwatch.ElapsedMilliseconds / 1000 + " Sekunden");
dataComparison[0] = measureData;
if(smoothing == true)
{
smoothMeasureData(xl);
}
}
private static void smoothMeasureData(Excelattributes xl)
{
if(temp != null)
{
try
{
int[] smoothParameters = new int[]{Convert.ToInt32(temp[0]), Convert.ToInt32(temp[1])};
if(smoothParameters[1] == 0) {smoothParameters[1] = 1;}
PointPairList smoothedData = new PointPairList();
MessageBox.Show("Glätte...\n" + smoothParameters[0] + " " + measureData.Count);
for(int i = (smoothParameters[0] -1); i < measureData.Count; i += smoothParameters[1])
{
double durchschnittX = 0;
double durchschnittY = 0;
for(int x = i; x > (i - (smoothParameters[0])); x --)
{
durchschnittX += measureData.ElementAt(x).X;
durchschnittY += measureData.ElementAt(x).Y;
}
durchschnittX /= (double) smoothParameters[0];
durchschnittY /= (double) smoothParameters[0];
smoothedData.Add(new PointPair(durchschnittX, durchschnittY));
}
dataComparison[0] = measureData;
dataComparison[1] = smoothedData;
writeToXLSX(smoothedData, xl);
}
catch(Exception exception)
{
MessageBox.Show(exception.Message, "Exception");
}
}
}
private static void writeToXLSX(PointPairList smoothedData, Excelattributes xl)
{
try
{
xl.Worksheet = (ExcelRefer.Worksheet) xl.Workbook.Worksheets.get_Item("Sheet1");
xl.Worksheet.Name = "Smoothed result";
xl.Workbook.Save();
xl.Workbook.Close(true, null, null);
xl.Range = xl.Worksheet.UsedRange;
Debug.WriteLine("Saved");
}
catch(Exception exception)
{
MessageBox.Show(exception.Message);
}
}
}
Have you tried closing Excel when you've finished?
I can't quite work out where you are gettng xl from but the following code works for me:
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
Workbook book = xlApp.Workbooks.Open(#"C:\test.xlsx");
Worksheet xl = book.Worksheets.get_Item("sheet1");
xl.Name = "Smoothed result";
book.Save();
book.Close();
Edit
After seeing the code you are using to open the workbook I think the issue is there. You are opening the file using:
xl.Workbook = xl.App.Workbooks.Open(s, 0, true, 5, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
The third parameter is a ReadOnly parameter which you have set to true. Try setting that to false.
I try to rewrite pct2rgb.py script into C# (this script gets 8-bit TIFF image and changes the bit depth of it into 24-bit). It worked when its output was stored on the HDD. I want to change the script a little. It should return Dataset on-the-fly w/o storing it on the disk. It works... Almost... The problem is that the returned Dataset contains monochromatic data... I don't really know why. Maybe it's caused by the change of a driver from GTiff to MEM (Driver gTiffDriver = Gdal.GetDriverByName("MEM");). But I don't know how to use GTiff driver and not to store the data on the HDD...
Here's my class:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using OSGeo.GDAL;
using OSGeo.OGR;
using OSGeo.OSR;
using Driver = OSGeo.GDAL.Driver;
using Encoder = System.Drawing.Imaging.Encoder;
using PixelFormat = System.Drawing.Imaging.PixelFormat;
namespace RasterLoader
{
public class TiffConverter
{
private string _format = "GTiff";
private string _srcFileName = null;
private int _outBands = 3;
private int _bandNumber = 1;
private string[] _args;
public TiffConverter(string[] args)
{
_args = args;
}
public Dataset Convert8To24Bit()
{
Gdal.AllRegister();
string[] argv = Gdal.GeneralCmdLineProcessor(_args, 0);
int i = 1;
while (i < argv.Count())
{
string arg = argv.ElementAt(i);
switch (arg)
{
case "-of":
i++;
_format = argv[i];
break;
case "-b":
i++;
_bandNumber = int.Parse(argv[i]);
break;
case "-rgba":
_outBands = 4;
break;
default:
if (string.IsNullOrEmpty(_srcFileName))
{
_srcFileName = argv[i];
}
else
{
Usage();
}
break;
}
i++;
}
string tmpFileName = _srcFileName + ".bak";
// open source file
Dataset srcDS = Gdal.Open(_srcFileName, Access.GA_ReadOnly);
if (srcDS == null)
{
throw new Exception("Unable to open " + _srcFileName + ".");
}
Band srcBand = srcDS.GetRasterBand(_bandNumber);
// ensure we recognise the driver
Driver dstDriver = Gdal.GetDriverByName(_format);
if (dstDriver == null)
{
throw new Exception("\"" + _format + "\" not registered.");
}
// build color table
int[][] lookup = new int[4][];
lookup[0] = Enumerable.Range(0, 256).ToArray();
lookup[1] = Enumerable.Range(0, 256).ToArray();
lookup[2] = Enumerable.Range(0, 256).ToArray();
lookup[3] = new int[256];
for (i = 0; i < 256; i++)
{
lookup[3][i] = 255;
}
ColorTable ct = srcBand.GetRasterColorTable();
if (ct != null)
{
for (i = 0; i < Math.Min(256, ct.GetCount()); i++)
{
ColorEntry entry = ct.GetColorEntry(i);
for (int j = 0; j < 4; j++)
{
switch (j)
{
case 0:
lookup[j][i] = entry.c1;
break;
case 1:
lookup[j][i] = entry.c2;
break;
case 2:
lookup[j][i] = entry.c3;
break;
case 3:
lookup[j][i] = entry.c4;
break;
}
}
}
}
// create the working file
string tifFileName = string.Empty;
if (_format.Equals("GTiff", StringComparison.OrdinalIgnoreCase))
{
tifFileName = tmpFileName;
}
else
{
tifFileName = Path.Combine(Directory.GetParent(tmpFileName).Name, "temp.gif");
}
// Driver gTiffDriver = Gdal.GetDriverByName("GTiff");
Driver gTiffDriver = Gdal.GetDriverByName("MEM");
Dataset tifDS = gTiffDriver.Create(tifFileName, srcDS.RasterXSize, srcDS.RasterYSize, _outBands, DataType.GDT_Byte,
new string[] {});
// we should copy projection information and so forth at this point
tifDS.SetProjection(srcDS.GetProjection());
double[] geotransform = new double[6];
srcDS.GetGeoTransform(geotransform);
tifDS.SetGeoTransform(geotransform);
if (srcDS.GetGCPCount() > 0)
{
tifDS.SetGCPs(srcDS.GetGCPs(), srcDS.GetGCPProjection());
}
// do the processing one scanline at a time
for (int iY = 0; iY < srcDS.RasterYSize; iY++)
{
byte[] srcData = new byte[srcDS.RasterXSize*1];
srcBand.ReadRaster(0, iY, srcDS.RasterXSize, 1, srcData, srcDS.RasterXSize, 1, 0, 0);
for (int iBand = 0; iBand < _outBands; iBand++)
{
int[] bandLookup = lookup[iBand];
int[] dstData = new int[srcData.Count()];
for (int index = 0; index < srcData.Count(); index++)
{
byte b = srcData[index];
dstData[index] = bandLookup[b];
}
tifDS.GetRasterBand(iBand + 1).WriteRaster(0, iY, srcDS.RasterXSize, 1, dstData,
srcDS.RasterXSize, 1, 0, 0);
}
}
return tifDS;
}
private void Usage()
{
Console.WriteLine("Usage: pct2rgb.py [-of format] [-b <band>] [-rgba] source_file dest_file");
throw new Exception("Bad arguments.");
}
}
Ok. I found a solution. My problem was I tried to convert all the files (even in a good format). Then ct variable (ColorTable) was null.
Solution:
if (ct != null)
{
// same code here
}
else
{
return srcDS;
}