|
Ok, that is correct, but then the question is how to write the changes back to the fixeddocument?
If I write to writer I will get a :
Package already has a root DocumentSequence or FixedDocument.
And I could not find a way to write it back to destination. Do you know how to do that?
|
|
|
|
|
I am not familiar with the XPS API so I would suggest you go back to the documentation to see what sequence is suggested.
Veni, vidi, abiit domum
|
|
|
|
|
Actually, that is the problem. I make some changes, but there is now way I could find that allows me to write the changes back to the file.
|
|
|
|
|
|
Yes, but it is a C++ library and my application is C# 
|
|
|
|
|
|
Good morning.
I have created a library of functions in C#, and I am testing them to see if they work in both VBA and on a spreadsheet (I am ok if they only work in VBA).
I have C# code to display the LastColumn and the LastRow in a spreadsheet as follows:
public string FindLastColumn(Worksheet xlWorkSheet)
{
int nInLastCol = 0;
nInLastCol = xlWorkSheet.Cells.Find("*", System.Reflection.Missing.Value, System.Reflection.Missing.Value,
System.Reflection.Missing.Value, XlSearchOrder.xlByColumns,XlSearchDirection.xlPrevious,
false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Column;
return GetExcelColumnName(nInLastCol);
}
private string GetExcelColumnName(int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName;
}
public long FindLastRow(Worksheet xlWorkSheet)
{
long nInLastRow = 0;
nInLastRow = xlWorkSheet.Cells.Find("*", System.Reflection.Missing.Value,
System.Reflection.Missing.Value, System.Reflection.Missing.Value,
XlSearchOrder.xlByRows,XlSearchDirection.xlPrevious,
false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Row;
return nInLastRow;
}
The FindLastColumn code works in VBA, but the FindLastRow does not, and neither works on a sheet (not sure how to correctly pass in the current sheet). The error is: Function or interface marked as retricted, or the function uses an Automation type not supported in Visual Basic.
VBA:
Dim TSExcelLib As New TechSolutionsXLLibrary.ExcelFunctions
Private Sub CommandButton1_Click()
MsgBox TSExcelLib.FindLastColumn(Sheets("Sheet1")) 'Works
MsgBox TSExcelLib.FindLastColumn(Sheet1) 'Works
MsgBox TSExcelLib.FindLastColumn(Sheets("Sheet1")) 'Doesn't work
MsgBox TSExcelLib.FindLastColumn(Sheet1) 'Doesn't work
Any insight would be greatly appreciated. WHEELS
|
|
|
|
|
I'm not an Office dev, but is there any particular reason you wouldn't use worksheet.UsedRange() and just return the appropriate row or column value?
Or...Worksheets("name").Cells.SpecialCells(xlCellTypeLastCell).Row ?
|
|
|
|
|
It has been a while since I created the code, and I don't recall why I took that approach, but I can give the UsedRange 'method' a try. Thank you for your reply. WHEELS
|
|
|
|
|
The UsedRange in Excel is notoriously unreliable - if the cursor has been moved to a blank cell outside the range of your data, Excel often sets the UsedRange to that cell, meaniing that you can potentially end up by reading large numbers of blank rows when you don't need to
=========================================================
I'm an optoholic - my glass is always half full of vodka.
=========================================================
|
|
|
|
|
Quote: The FindLastColumn code works in VBA, but the FindLastRow does not, and neither works on a sheet (not sure how to correctly pass in the current sheet). The error is: Function or interface marked as retricted, or the function uses an Automation type not supported in Visual Basic
Just a stab in the dark, but you have defined FindLastRow as "long". The VBA "Long" integer is 32 bit versus the c# "long" which is a 64 bit integer.
|
|
|
|
|
I am currently working a project using wpf. I want a promptBox that will allow the user enter some information which will be use in the app. Eg i want he user to enter some setting information in the promptwindow
|
|
|
|
|
So, create a Window that will display the prompt and TextBox for the user to enter into, along with a couple of buttons to OK or Cancel. Have a ViewModel behind this that the View will bind to as the DataContext .
|
|
|
|
|
The csv file has only about 450 lines with 55 variables separated by commas . . but takes about 120 seconds to populate the DataViewGrid.
Since the csv file will be updated throughout the day and used as an input for the app, I need to speed this up considerably. It's the parsing that is taking the time. Any ideas greatly appreciated.
After reading the csv file to lines (string array) . . .
for (int x = 0; x >= lines.GetUpperBound(0); x++)
{
DataGridView1.Rows[x].SetValues(lines[x].Split(','));
}
|
|
|
|
|
Populating the grid directly is VERY slow. You should be loading the data in a DataTable and binding the grid to that instead.
|
|
|
|
|
Thanks Dave.
Do you have a source I can go to get the minimum code to populate the DGV?
I believe what I have found is overkill . . since I only need to populate the DGV . . no queries needed. I'm having trouble adding correct references. I added System.Web & following using statement:
using System.Web.Configuration;
I didn't think . . .
using System.Data.Odbc;
would be necessary to only populate the DGV file?
I have copied csv records into . .
string[] lines = system.IO.File.ReadAllLines("C:\\TaxLtrExport\\ClientInfoMaster.csv");
Trying to get references & code to populate the DGV.
Thanks for any suggestions.
John
|
|
|
|
|
Again, You have the lines from the CSV file. Parse them and put them into a DataTable object, then bind the DGV to the DataTable. No, I don't have code to give you.
Also, the DGV is a Windows Forms control. You don't need the System.Web namespaces at all.
|
|
|
|
|
Thanks for your input.
OK . . I have parsed the lines, adding them to a DataTable. I then bound to my DGV.
The time to populate the dgv decreased from 120 sec to 15 sec . . . nice improvement.
My program interacts with other DGVs and it is necessary to add rows to my DGV. Note that the program worked without using a DataTable, but was slow populating the data from the CSV file to the DGV. I have no problem with speed issues on other functions . . adding rows directly to the DGV, sorting, etc.
Now after using a DataTable as a data source for the DGV (only for populating the DGV) I get an error when other functions run to add rows to the DGV. I understand I could just work thru the bound DataTable, but I would prefer not. After I bound the data table to the dgv . . .
DataGridView1.DataSource = csvData; //csvData is DataTable
But when functions try to run that add rows to dgv,
DataGridView1.Rows.Add();
I get the error . . .
Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound.
So I would like to use the datatable only to initially populate the dgv and then UNBIND, allowing the program to run as it did before, having resolved the speed issue in populating.
I have used the following attempting to unbind, but still get the same error above.
DataGridView1.DataBindings.Clear();
DataGridView1.Columns.Clear(); //NO . . this deletes ALL rows.
DataGridView1.DataSource.Equals(null);
Any suggestions would be appreciated.
John
|
|
|
|
|
Bound grids cannot have rows arbitrarily deleted from or added to them. You have to delete/add them from/to the source they are bound to.
You have a choice. Bind the grid and gain speed or don't bind the grid and loose the speed. There is no such thing as "bind and forget" the way you describe. Once you unbind the grid, it forgets about all the data that came across that binding.
I hear you asking "but I've seen rows being added to bound grids?". They're not adding the row to the grid. The grid is editing a blank row that was added to the source by the grid through a BindingNavigator.
The fastest your going to get is a databound grid that has Virtual mode turned on.
There is no such as Virtual mode when manually adding rows to an unbound grid. It only works with bound sources.
|
|
|
|
|
Appreciate your input . . . I understand. I also understand I may be in over my head. I'm not a programmer by profession . . I have written many programs related to my work as CPA tax planner & investment advisor. Of course, I would like to have a databound grid.
I have not bound anything before. Having a hard time getting head around it . . may have to start from scratch instead of trying to edit what I have. Hard to decide since what I have (unbound)works but is slow.
Basically, I have a master csv file that takes another csv file (generatded by a commercial tax program) and updates my master csv file. One question . . . my unbound program adds any new row (from small csv file) to master csv file. My changed program that now has a DGV bound to a datatable. Where I have added a row to my DGV . . . do I now change the coding to add a row to the datatable?
Dave, thanks again for your input. If you think I need to start over from scratch, can you suggest any tutorials that will help me get the concept (binding DGV - datatable in my head)?
|
|
|
|
|
Yes, you would have to add the row to the DataTable, then refresh the grid.
I don't have any tutorials on the DGV, but Google does. "datagridview tutorial[^]"
|
|
|
|
|
The other solution is to read the CSV using an existing reader. This would probably do it: A Fast CSV Reader[^]
(it's certainly a better approach than reading the file as lines, since CSV files can contain newlines as part of the text if it's within an open set of quotes)
Then it's pretty simple:
using (CachedCsvReader csv = new CachedCsvReader(new StreamReader(@"D:\Temp\Data.csv"), true))
{
dgvData.DataSource = csv;
}
That loads a couple of thousand rows of 22 columns in a second or so.
Never underestimate the power of stupid things in large numbers
--- Serious Sam
|
|
|
|
|
As others have already said, you'd like to synchronize with the CSV, not use it directly as your datasource. Also, binding takes some time that can be avoided by putting the datagridview in virtual mode[^].
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
I´m working on a game using XNA and C#.
It´s a kind of two (or more) uboat-game where you place an uboat somewhere and then the opponent are going to find the uboat.
The game is maybe going to be an online-game or maybe between two computers.
I also need chat but that can be a separat program.
Anyway, right now I have a form which contains a picturebox where the actual game are.
I have a button in the form and would like to be able to affect the sprites using that button.
Right now the uboat is placed in the upper left corner. Then I want to move the uboat to destination of my choice.
However I can't affect hte uboat (enemy) with the button once the game has started.
Is it even possible?
I'm quite new to XNA and I have used this a tutorial:
Here´s my code:
Program:
using System;
namespace WindowsGame1
{
#if WINDOWS || XBOX
static class Program
{
static void Main(string[] args)
{
Form1 form = new Form1();
form.Show();
Game1 game = new Game1(form.getDrawSurface());
game.Run();
}
}
#endif
}
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Game1 game1 = new Game1();
int counter = 1;
public IntPtr getDrawSurface()
{
return pctSurface.Handle;
}
private void button1_Click(object sender, EventArgs e)
{
game1.buttonHit(350, 450, true);
counter++;
label1.Text = counter.ToString();
}
}
}
Game1
public class Game1 : Microsoft.Xna.Framework.Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private Player player;
private Player player2;
private Enemy enemy;
private Texture2D backgroundTexture;
int screenWidth;
int screenHeight;
GraphicsDevice device;
Rectangle textBox;
private IntPtr drawSurface;
int x;
int y;
bool isActive = false;
public void buttonHit(int X, int Y, bool IsActive)
{
x = X;
y = Y;
isActive = IsActive;
}
public Game1(IntPtr drawSurface)
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.drawSurface = drawSurface;
graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
System.Windows.Forms.Control.FromHandle((this.Window.Handle)).VisibleChanged += new EventHandler(Game1_VisibleChanged);
}
public Game1()
{
}
void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle =
drawSurface;
}
private void Game1_VisibleChanged(object sender, EventArgs e)
{
if (System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible == true)
System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible = false;
}
protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 1500;
graphics.PreferredBackBufferHeight = 800;
graphics.IsFullScreen = false;
graphics.ApplyChanges();
Window.Title = "Enigma";
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
device = graphics.GraphicsDevice;
enemy = new Enemy(Content.Load<Texture2D>("images/enemies/uboat2_small"), 0, 0);
player = new Player(Content.Load<Texture2D>("images/player/Ship"), 300, 400);
if (isActive == true)
player2 = new Player(Content.Load<Texture2D>("images/player/Ship"), x, y);
backgroundTexture = Content.Load<Texture2D>("images/Background/Atlanten3_1");
screenWidth = device.PresentationParameters.BackBufferWidth;
screenHeight = device.PresentationParameters.BackBufferHeight;
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
player.update(Window);
if (isActive == true)
player2.update(Window);
enemy.Update2(Window, x, y);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
DrawScenery();
player.Draw(spriteBatch);
if (isActive == true)
player2.Draw(spriteBatch);
enemy.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
private void DrawScenery()
{
Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);
spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
}
}
}
GameObject-class: (base-class):
public class GameObject
{
public Texture2D texture; // Rymdskeppets textur (Från Player-klassen)
public Vector2 ship_vector; // Rymnskeppets koordinater (Från Player-klassen)
public GameObject(Texture2D texture, float X, float Y) //Delvis från Player-klassen
{
this.texture = texture;
this.ship_vector.X = X;
this.ship_vector.Y = Y;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, ship_vector, Color.White);
}
public float X //Egenskap för att komma åt skeppets vågräta position
{
get
{
return ship_vector.X;
}
set
{
ship_vector.X = value;
}
}
public float Y //Egenskap för att komma åt skeppets lodräta position
{
get
{
return ship_vector.Y;
}
set
{
ship_vector.Y = value;
}
}
public float Width //Egenskap för att komma åt bredd på ship_texture
{
get
{
return texture.Width;
}
}
public float Height //Egenskap för att komma åt höjd på ship_texture
{
get
{
return texture.Height;
}
}
}
}
MovingObject-class:
public abstract class MovingObject : GameObject
{
public Vector2 ship_speed;
public MovingObject(Texture2D texture, float X, float Y, float speedX, float speedY) : base(texture, X, Y)
{
this.ship_speed.X = speedX;
this.ship_speed.Y = speedY;
}
}
}
Player-class:
public class Player : MovingObject
{
bool isAlive = true;
public Player(Texture2D texture, float X, float Y) : base(texture, X, Y, 0.05f, 0.05f)
{
}
public void update(GameWindow window)
{
KeyboardState keyboardState = Keyboard.GetState();
if (ship_vector.X <= window.ClientBounds.Width - texture.Width && ship_vector.X >= 0)
if (keyboardState.IsKeyDown(Keys.NumPad5))
ship_vector.X += 1;
ship_vector.X -= ship_speed.X;
ship_vector.Y -= ship_speed.Y;
if (ship_vector.X > window.ClientBounds.Width - texture.Width || ship_vector.X < 0)
ship_speed.X *= -1;
if (ship_vector.Y > window.ClientBounds.Height)
isAlive = false;
}
public bool IsAlive
{
get { return isAlive; }
set { isAlive = value; }
}
}
}
Enemy-class:
<pre lang="c#">
public class Enemy : MovingObject
{
bool isAlive = true;
public Enemy(Texture2D texture, float X, float Y) : base(texture, X, Y, 0.05f, 0.05f)
{
}
public void Update(GameWindow window)
{
ship_vector.X += ship_speed.X;
ship_vector.Y += ship_speed.Y;
if (ship_vector.X > window.ClientBounds.Width - texture.Width || ship_vector.X < 0)
ship_speed.X *= -1;
if (ship_vector.Y > window.ClientBounds.Height)
isAlive = false;
}
public void Update2(GameWindow window, int x, int y)
{
ship_vector.X = x;
ship_vector.Y = y;
}
public bool IsAlive
{
get { return isAlive; }
set { isAlive = value; }
}
}
}
|
|
|
|
|
Change Form1 to this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Game1 game1;
int counter = 1;
public Game1 Game { get { return game1; } set { game1 = value; } }
public IntPtr getDrawSurface()
{
return pctSurface.Handle;
}
private void button1_Click(object sender, EventArgs e)
{
game1.buttonHit(350, 450, true);
counter++;
label1.Text = counter.ToString();
}
}
}
Then change Program.cs to:
static void Main(string[] args)
{
Form1 form = new Form1();
Game1 game = new Game1(form.getDrawSurface());
form.Game = game;
form.Show();
game.Run();
}
Can you see why? You create a game in the Program.cs file, and you create another one in the Form1.cs file. Even though the names are the same, they are not the same game, essentially you have two Game1 objects created. The one you are talking to in Form1 is not the one you created when the program starts. Somehow you need to give Form1 a reference to the game you created. This is one way, there are others, for example, you could also do this:
Form1.cs:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int counter = 1;
public IntPtr getDrawSurface()
{
return pctSurface.Handle;
}
private void button1_Click(object sender, EventArgs e)
{
Program.game.buttonHit(350, 450, true);
counter++;
label1.Text = counter.ToString();
}
}
}
Then change Program.cs to:
static Game1 game;
static void Main(string[] args)
{
Form1 form = new Form1();
form.Show();
game = new Game1(form.getDrawSurface());
game.Run();
}
There are many ways to skin a cat, but these are two of the easiest.
|
|
|
|
|