I have two ViewControllers (ViewController A, ViewController B). Both are UITableviewController.
In ViewController A, I get the data from a database an put it to List<string>, so I can Display it.
I have a Navigationbar-button to go to ViewController B. In ViewController B I have List with additional Items. I can add the additional item to the database with a swipe action. This works.
When I go back to ViewController A I want to update my List, but I don't know how :(
I tried it with ViewDidAppear, but it does not work.
ViewController A:
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear(animated);
NavigationItem.Title = "Anwendungsfälle";
// Hier geht es zum Hinzufügen der Anwendungsfeleder / -fälle oder Maßnahmen zum bestehenden Katalog
this.NavigationItem.SetRightBarButtonItem(
new UIBarButtonItem(UIBarButtonSystemItem.Add,
(sender, args) =>
{
var alertController = UIAlertController.Create("Anwendungsfeld hinzufügen", "Wählen Sie eine Option aus", UIAlertControllerStyle.ActionSheet);
// Hier geht es zur Vorgefertigten Bibliothek
alertController.AddAction(UIAlertAction.Create("Aus Bibliothek hinzufügen", UIAlertActionStyle.Default, (Action) =>
{
AddAnFaViewController controller = this.Storyboard.InstantiateViewController("AddAnFaViewController") as AddAnFaViewController;
controller.firmabereich = firmabereich;
controller.bereich = bereich;
controller.zieleid = zieleid;
controller.idafe = idafe;
this.NavigationController.PushViewController(controller, true);
}));
// Abbrechen Knopf
alertController.AddAction(UIAlertAction.Create("Abbrechen", UIAlertActionStyle.Cancel, alert => Console.WriteLine("Cancel clicked")));
PresentViewController(alertController, true, null);
}),
true);
var lines = new List<string>();
using (MySqlConnection connection = new MySqlConnection("Server=xxxx;Port=3306;database=xxxxb;User Id=xxxxx;Password=xxxx;charset=utf8"))
{
string query = $"SELECT DISTINCT Anwendungsfall FROM {firmabereich} WHERE IDAFE LIKE '{idafe}' ORDER BY Anwendungsfall ASC";
string query2 = $"SELECT DISTINCT IDAFA FROM {firmabereich} WHERE IDAFE LIKE '{idafe}' ORDER BY Anwendungsfall ASC";
string query3 = $"SELECT DISTINCT PrioAnFa, Anwendungsfall FROM {firmabereich} WHERE IDAFE LIKE '{idafe}' ORDER BY Anwendungsfall ASC";
MySqlCommand command = new MySqlCommand(query, connection);
MySqlCommand command2 = new MySqlCommand(query2, connection);
MySqlCommand command3 = new MySqlCommand(query3, connection);
connection.Open();
using (MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
anwendungsfälle.Add(reader.GetString(0));
}
}
using (MySqlDataReader reader = command2.ExecuteReader())
{
while (reader.Read())
{
anwendungsfälleid.Add(reader.GetString(0));
}
}
using (MySqlDataReader reader = command3.ExecuteReader())
{
while (reader.Read())
{
prio.Add(reader.GetString(0));
}
}
}
TableView.RowHeight = UITableView.AutomaticDimension;
TableView.EstimatedRowHeight = 40f;
TableView.ReloadData();
}
Since reloading data affects the User Interface directly you need to reload data in GCD.
DispatchQueue.main.async {
TableView.ReloadData();
}
GCD is Apple's multi threading concept; so take a time to understand how it works throughout the Application Life Cycle.
This could be the good introduction
Related
I am developing a POS application in windows 8.1 (Universal App).
Order receipt will be printed from the application and even I am able to do so.
Printer - EPSON TM-U220D
Input - A grid is being created pragmatically with dynamic content within the ViewModel. So this grid is the input for printer
Output - In the print preview (Attahced pic 1) all looks good but when the receipt is actually printed then content is cut off from the end (Attahced pic 2)
PIC 1
PIC 2
Observations -
If I print a normal text file manually using print command (Right click file and then print), then all content is printed perfectly.
If I print that SAME content, from the application, by creating Dynamic grid, then with Small font size print is good but with bit bigger font size content again cuts off.
Tried -
Optimized the code for Creating Gird, by specifying height
Questions-
If preview is all good then why not output
Did anyone tried using ePOS-Print_SDK_141020E for Windows Store app?
Generate Dynamic Grid Code
private void AddRows(Grid grid, int count)
{
for (int i = 0; i < count; i++)
{
RowDefinition row = new RowDefinition();
row.Height = GridLength.Auto;
grid.RowDefinitions.Add(row);
}
}
private void AddColumns(Grid grid, int count)
{
for (int i = 0; i < count; i++)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
}
private TextBlock CreateTextBlock(string text, Color color, FontWeight fw, double fs = 10, int thick = 5)
{
if (color == null) color = Colors.Black;
TextBlock txtBlock1 = new TextBlock();
txtBlock1.Text = text;
txtBlock1.FontSize = fs;
txtBlock1.FontWeight = fw;
txtBlock1.Foreground = new SolidColorBrush(color);
txtBlock1.VerticalAlignment = VerticalAlignment.Center;
txtBlock1.Margin = new Thickness(thick);
return txtBlock1;
}
private async Task<Grid> CreateDynamicWPFGrid()
{
Grid ParentGrid = new Grid();
AddRows(ParentGrid, 8);
/* Start First Grid*/
Grid DynamicGrid = new Grid();
DynamicGrid.Width = 230;
DynamicGrid.HorizontalAlignment = HorizontalAlignment.Left;
DynamicGrid.VerticalAlignment = VerticalAlignment.Top;
DynamicGrid.Margin = new Thickness(24, 0, 0, 0);
AddColumns(DynamicGrid, 2);
AddRows(DynamicGrid, 3);
TextBlock txtBlock1 = CreateTextBlock(DateTime.Now.ToString("M/d/yy"), Colors.Black, FontWeights.Normal);
Grid.SetRow(txtBlock1, 0);
Grid.SetColumn(txtBlock1, 1);
.
.
.
.
Return ParentGrid;
}
Printer Events Code
//Register Print Contract
async Task RegisterPrintContract()
{
PrintManager manager = PrintManager.GetForCurrentView();
manager.PrintTaskRequested += OnPrintTaskRequested;
await PrintManager.ShowPrintUIAsync();
}
//Unregister Print Contract
void UnregisterPrintContract()
{
PrintManager printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested -= OnPrintTaskRequested;
}
void OnPrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
// If I need to be asynchronous, I can get a deferral. I don't *need*
// to do this here, I'm just faking it.
var deferral = args.Request.GetDeferral();
PrintTask printTask = args.Request.CreatePrintTask("My Print Job", OnPrintTaskSourceRequestedHandler);
printTask.Completed += OnPrintTaskCompleted;
deferral.Complete();
}
void OnPrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args)
{
// TODO: Tidy up.
this._document = null;
this._pages = null;
}
async void OnPrintTaskSourceRequestedHandler(PrintTaskSourceRequestedArgs args)
{
var deferral = args.GetDeferral();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
this._document = new PrintDocument();
this._document.Paginate += OnPaginate;
this._document.GetPreviewPage += OnGetPreviewPage;
this._document.AddPages += OnAddPages;
// Tell the caller about it.
args.SetSource(this._document.DocumentSource);
});
deferral.Complete();
}
void OnAddPages(object sender, AddPagesEventArgs e)
{
// Loop over all of the preview pages and add each one to add each page to be printied
// We should have all pages ready at this point...
foreach (var page in this._pages)
{
//this._pages[page.Key]
this._document.AddPage(this._pages[page.Key]);
}
PrintDocument printDoc = (PrintDocument)sender;
// Indicate that all of the print pages have been provided
printDoc.AddPagesComplete();
}
async void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
Grid x = await CreateDynamicWPFGrid();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// NB: assuming it's ok to keep all these pages in
// memory. might not be the right thing to do
// of course.
if (this._pages == null)
{
this._pages = new Dictionary<int, UIElement>();
}
if (!this._pages.ContainsKey(e.PageNumber))
{
this._pages[e.PageNumber] = x;
}
if (this._document == null)
this._document = new PrintDocument();
this._document.SetPreviewPage(e.PageNumber, this._pages[e.PageNumber]);
}
);
}
async void OnPaginate(object sender, PaginateEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// I have one page and that's *FINAL* !
this._document.SetPreviewPageCount(e.CurrentPreviewPageNumber, PreviewPageCountType.Final);
});
}
I'm using the ZXing MobileScanner lib with my xamarin project for iOS (MonoTouch).
I set up the scanning, it is working fine, reading my QRCode and having the correct result.
After reading the QRCode I want to show another ViewController. I set a property in the second Controller with the result from scanning and then want to show the controller.
The second view is not shown on screen. No errors, no feedback, simply not shown.
I guess, the MobileScanner builds up its own View (which can be seen in the source of the lib) and adds this to the NavigationController - and that this causes my Controller to stay "behind". Testing with simply redirecting to my controller on button clicks is working fine.
I also tried to "dispose" the view by calling scanner.Cancel(), but this results in
Warning: Attempt to dismiss from view controller <UINavigationController: 0x19a0c60> while a presentation or dismiss is in progress!
Here is my code, any help on how to display my view is appreciated.
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
scanner = new MobileBarcodeScanner(this.NavigationController);
this.btnScan.TouchUpInside += (sender, e) => {
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of the default overlay
scanner.TopText = "Ticket vor den Scanner halten";
scanner.BottomText = "Code wird automatisch eingelesen";
//Start scanning
scanner.Scan ().ContinueWith((t) =>
{
//Our scanning finished callback
if (t.Status == System.Threading.Tasks.TaskStatus.RanToCompletion){
string msg = "";
ZXing.Result result = t.Result;
if (result != null && !string.IsNullOrEmpty (result.Text)) {
scanner.Cancel();
if(this.ticketScreen == null) {
this.ticketScreen = new TicketScreen();
}
this.ticketScreen.ticketUrl = result.Text;
this.NavigationController.PushViewController(this.ticketScreen, true);
} else {
msg = "Code nicht erkannt!";
this.InvokeOnMainThread(() => {
var av = new UIAlertView("Fehler!", msg, null, "OK", null);
av.Show();
});
}
}
});
};
}
I use this.InvokeOnMainThread(() and it works fine in my code.
The solution for you is:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
scanner = new MobileBarcodeScanner(this.NavigationController);
this.btnScan.TouchUpInside += (sender, e) => {
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of the default overlay
scanner.TopText = "Ticket vor den Scanner halten";
scanner.BottomText = "Code wird automatisch eingelesen";
//Start scanning
scanner.Scan ().ContinueWith((t) =>
{
//Our scanning finished callback
if (t.Status == System.Threading.Tasks.TaskStatus.RanToCompletion){
string msg = "";
ZXing.Result result = t.Result;
if (result != null && !string.IsNullOrEmpty (result.Text)) {
scanner.Cancel();
this.InvokeOnMainThread(() =>
{
if(this.ticketScreen == null) {
this.ticketScreen = new TicketScreen();
}
this.ticketScreen.ticketUrl = result.Text;
this.NavigationController.PushViewController(this.ticketScreen, true);
});
} else {
msg = "Code nicht erkannt!";
this.InvokeOnMainThread(() => {
var av = new UIAlertView("Fehler!", msg, null, "OK", null);
av.Show();
});
}
}
});
};
}
In Pivot control all Pivot items content is loading at a time in WindowsPhone 7.1 I am developing Cross Platform application.
Issue:
In my application each Pivot Item having WebBrowser control. When loading all Pivot Item's Content at a time java script calls are conflicted.
Requirement:
If Pivot Control having 4 Pivot Items like item1, item2, item3 and item4, then load item2 after the content of item1 load finished.
EDIT 1: I have tried the following code http://www.c-sharpcorner.com/UploadFile/1d42da/synchronization-events-and-wait-handles-in-C-Sharp/
ManualResetEvent mre = new ManualResetEvent(false);
foreach (PivotDetails pivotdetails in pivtdetailslist)
{
PivotItem pivotitem = new PivotItem();
pivotitem.Header = pivotdetails.header;
WebBrowserControl browsercontrol = new WebBrowserControl(this);
browsercontrol.Navigate(pivotdetails.url);
pivotitem.Content = browsercontrol;
mre.Reset();
myPivot.Items.Add(pivotitem);
mre.WaitOne();
}
private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
mre.Set();
}
EDIT1 Issue: Waiting screen only displaying not able to see Design page.
I have used the following code for "Wait to complete the event"
foreach (PivotDetails pivotdetails in pivtdetailslist)
{
PivotItem pivotitem = new PivotItem();
pivotitem.Header = pivotdetails.header;
WebBrowserControl browsercontrol = new WebBrowserControl(this);
pivotitem.Content = browsercontrol;
mre.Reset();
myPivot.Items.Add(pivotitem);
mre.WaitOne();
}
private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
myPivot.isHitTestVisible = true;
}
private void myPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Pivot pivot = sender as Pivot;
PivotItem currentPivot= pivot.SelectedItem as PivotItem;
if (currentPivot.Content is WebBrowserControl)
{
WebBrowserControl bc = currentPivot.Content as WebBrowserControl;
if (bc.getWebView().Source == null)
{
bc.Navigate(pivtdetailslist[pivot.SelectedIndex].url);
bc.getWebView().LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(webBrowser_LoadCompleted);
myPivot.IsHitTestVisible = false;
}
}
}
I am having issues with my application. I have a db table for a print queue. When I read from that table in a loop, once I add that record to the view model, I then want to delete it from the database...this would be the most efficient way to do it, but EF barks:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I've tried using multiple contexts... but that didn't seem to work either. I've seen articles like Rick Strahl's, but frankly it was above my level of understanding, and not exactly sure if it helps my issue here and seemed quite an in depth solution for something as simple as this.
Is there a simple way to accomplish what I am trying to achieve here?
Here is my code:
public List<InventoryContainerLabelViewModel> CreateLabelsViewModel(int intFacilityId)
{
var printqRep = new Repository<InventoryContainerPrintQueue>(new InventoryMgmtContext());
var printqRepDelete = new Repository<InventoryContainerPrintQueue>(new InventoryMgmtContext());
IQueryable<InventoryContainerPrintQueue> labels =
printqRep.SearchFor(x => x.FacilityId == intFacilityId);
List<InventoryContainerLabelViewModel> labelsViewModel = new List<InventoryContainerLabelViewModel>();
if (labels.Count() > 0)
{
//Get printq record
foreach (InventoryContainerPrintQueue label in labels)
{
IEnumerable<InventoryContainerDetail> icDtls =
label.InventoryContainerHeader.InventoryContainerDetails;
//Get print details
foreach (InventoryContainerDetail icDtl in icDtls)
{
labelsViewModel.Add(new InventoryContainerLabelViewModel()
{
...
populate view model here
}
);//Add label to view model
} //for each IC detail
//Delete the printq record
printqRepDelete.Delete(label); <======== Error Here
} //foreach label loop
}//label count > 0
return labelsViewModel.ToList();
}
In the end, I added a column to the printq table for status, then in the the loop updated it to processed, then called a separate method to delete it.
public List<InventoryContainerLabelViewModel> CreateLabelsViewModel(int intFacilityId)
{
InventoryMgmtContext dbContext = new InventoryMgmtContext();
var printqRep = new Repository<InventoryContainerPrintQueue>(dbContext);
IEnumerable<InventoryContainerPrintQueue> unprintedPrtqRecs =
printqRep.SearchFor(x => x.FacilityId == intFacilityId && x.Printed == false);
List<InventoryContainerLabelViewModel> labelsViewModel = new List<InventoryContainerLabelViewModel>();
if (unprintedPrtqRecs.Count() > 0)
{
//Get printq record
foreach (InventoryContainerPrintQueue unprintedPrtqRec in unprintedPrtqRecs)
{
IEnumerable<InventoryContainerDetail> icDtls =
unprintedPrtqRec.InventoryContainerHeader.InventoryContainerDetails;
//Get container details to print
foreach (InventoryContainerDetail icDtl in icDtls)
{
labelsViewModel.Add(new InventoryContainerLabelViewModel()
{
...
}
);//Get IC details and create view model
} //for each IC detail
unprintedPrtqRec.Printed = true;
printqRep.Update(unprintedPrtqRec, unprintedPrtqRec, false);
} //foreach label loop
//Commit updated to Printed status to db
dbContext.SaveChanges();
}//label count > 0
return labelsViewModel;
}
public ActionConfirmation<int> DeletePrintQRecs(int intFacilityId)
{
InventoryMgmtContext dbContext = new InventoryMgmtContext();
var printqRep = new Repository<InventoryContainerPrintQueue>(dbContext);
IEnumerable<InventoryContainerPrintQueue> printedPrtqRecs =
printqRep.SearchFor(x => x.FacilityId == intFacilityId && x.Printed == true);
foreach (InventoryContainerPrintQueue printedPrtqRec in printedPrtqRecs)
{
//Delete the printq record
printqRep.Delete(printedPrtqRec, false);
}
//Save Changes on all deletes
ActionConfirmation<int> result;
try
{
dbContext.SaveChanges();
result = ActionConfirmation<int>.CreateSuccessConfirmation(
"All Label Print Q records deleted successfully.",
1);
}
catch (Exception ex)
{
result = ActionConfirmation<int>.CreateFailureConfirmation(
string.Format("An error occured attempting to {0}. The error was: {2}.",
"delete Label Print Q records",
ex.Message),
1
);
}
return result;
}
I'm having a nightmare of a time trying to add a Chart to a MemoryStream in-memory.
I'm creating a Word document on the fly using OpenXML and I have a chart that is also being dynamically generated from data in the database.
I get the template from the database as a byte array, passing that into a method that also takes a business object that holds a bunch of data to populate bookmarks held within that template.
Here's the method:
public Stream Parse(byte[] array, AudiometryReport AudReport)
{
using (MemoryStream Stream = new MemoryStream())
{
Stream.Write(array, 0, (int)array.Length);
Stream.Position = 0;
using (document = WordprocessingDocument.Open(Stream, true))
{
XDocument doc = document.MainDocumentPart.GetXDocument();
List<XElement> bookmarks = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkStart")
.ToList();
PropertyInfo[] reportInfo = AudReport.GetType().GetProperties();
foreach (XElement bm in bookmarks)
{
try
{
if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);
var element = AddImageToDocument(document.MainDocumentPart, partId);
//var element = InsertImageXElement(partId);
//bm.ReplaceWith(new XElement(w + "r", element));
}
else
{
string val = reportInfo.Single(x => x.Name == bm.LastAttribute.Value).GetValue(AudReport, null).ToString();
bm.ReplaceWith(new XElement(w + "r",
new XElement(w + "t", val)));
}
}
catch
{ }
}
document.MainDocumentPart.PutXDocument();
//foreach (BookmarkStart bm in (IEnumerable<BookmarkStart>)document.MainDocumentPart.Document.Descendants<BookmarkStart>())
//{
// if (bm.Name == "AudiometryChart")
// {
// // Insert the chart object here.
// //AddImage(document);
// }
// populateStaffDetails(AudReport.Report.Employee, bm);
// populateAudiometryDetails(AudReport, bm);
//}
}
MemoryStream s = new MemoryStream();
Stream.WriteTo(s);
s.Position = 0;
return s;
}
}
The InsertImage image takes the MainDocumentPart and attaches a new ImagePart from the image I stream from the database. I pass the ID of that part back to the calling method.
private string InsertImage(MainDocumentPart docPart)
{
//DrawingsPart dp = docPart.AddNewPart<DrawingsPart>();
//ImagePart part = dp.AddImagePart(ImagePartType.Png, docPart.GetIdOfPart(dp));
ImagePart part = docPart.AddImagePart(ImagePartType.Png);
Chart cht = new ChartBuilder().DoChart(Data, new string[] { "Left", "Right", "Normal" });
using (MemoryStream ms = new MemoryStream())
{
cht.SaveImage(ms, ChartImageFormat.Png);
ms.Position = 0;
part.FeedData(ms);
}
//int count = dp.ImageParts.Count<ImagePart>();
int count = docPart.ImageParts.Count<ImagePart>();
return docPart.GetIdOfPart(part);
}
The last part is some serious nastiness that is allegdly required to add one image to one word document, but what the hell - here it is anyway:
private Run AddImageToDocument(MainDocumentPart docPart, string ImageRelId)
{
string ImageFileName = "Audiometry Chart Example";
string GraphicDataUri = "http://schemas.openxmlformats.org/drawingml/2006/picture";
long imageLength = 990000L;
long imageHeight = 792000L;
var run = new Run(
new Drawing(
new wp.Inline(
new wp.Extent() { Cx = imageLength, Cy = imageHeight },
new wp.EffectExtent()
{
LeftEdge = 19050L,
TopEdge = 0L,
RightEdge = 9525L,
BottomEdge = 0L
},
new wp.DocProperties()
{
Id = (UInt32Value)1U,
Name = "Inline Text Wrapping Picture",
Description = ImageFileName
},
new wp.NonVisualGraphicFrameDrawingProperties(
new a.GraphicFrameLocks() { NoChangeAspect = true }),
new a.Graphic(
new a.GraphicData(
new pic.Picture(
new pic.NonVisualPictureProperties(
new pic.NonVisualDrawingProperties() { Id = (UInt32Value)0U, Name = ImageFileName },
new pic.NonVisualPictureDrawingProperties()),
new pic.BlipFill(
new a.Blip() { Embed = ImageRelId },
new a.Stretch(
new a.FillRectangle())),
new pic.ShapeProperties(
new a.Transform2D(
new a.Offset() { X = 0L, Y = 0L },
new a.Extents() { Cx = imageLength, Cy = imageHeight }),
new a.PresetGeometry(
new a.AdjustValueList()) { Preset = a.ShapeTypeValues.Rectangle }))
) { Uri = GraphicDataUri }))
{
DistanceFromTop = (UInt32Value)0U,
DistanceFromBottom = (UInt32Value)0U,
DistanceFromLeft = (UInt32Value)0U,
DistanceFromRight = (UInt32Value)0U
}
));
return run;
}
So I've solved issues where the memory stream was causing problems by closing prematurely and probably a dozen other unnecessary amateur garden path problems but that image will just not show up in my document. Frustrating. Suggestions or divine inspiration very welcome right now.
(this question has been heavily edited so some answers may not relate to the wording of this question).
I've just tested your AddImageToDocument function in a small test
scenario using the following code:
string partId = ...
Run element = AddImageToDocument(newdoc.MainDocumentPart, partId);
Paragraph p = new Paragraph() { RsidParagraphAddition = "00EA6221", RsidRunAdditionDefault = "008D25CC" };
p.AppendChild(element);
newdoc.MainDocumentPart.Document.Body.Append(p);
// Save the word document here...
Everything works as expected and the image shows up in the word document.
Then I've come to the conclusion that the problem in your code must be the replacement of the bookmarkStart tag and the conversion
of the Run (containing the image) to an XElement.
So, I've modified your code in the following way (using XElement.Parse to convert
an OpenXmlElement to a XElement):
foreach (XElement bm in bookmarks)
{
try
{
if (bm.LastAttribute.Value == "AudiometryChart")
{
string partId = InsertImage(document.MainDocumentPart);
Run element = AddImageToDocument(document.MainDocumentPart, partId);
bm.ReplaceWith(XElement.Parse(element.OuterXml)); // Use XElement.Parse to convert an OpenXmlElement to an XElement.
}
else
{
... }
}
}
catch
{
}
}
The image now shows up in the word document.
Then I've analyzed the word document using the
OpenXml SDK productivity tool and found that the bookmarkEnd tags still exist in the document.
To remove those tags use the following code:
List<XElement> bookmarksEnd = doc.Descendants()
.Where(n => n.NodeType == XmlNodeType.Element && n.Name.LocalName == "bookmarkEnd")
.ToList();
foreach (XElement x in bookmarksEnd)
{
x.Remove();
}
Edit 3: :o)
Ok, I found the problem.
If you initialize the document's MemoryStream with the doc content, the buffer will be fixed in size and not editable. Just changed the init to write the doc content after creation and all seemd to work fine.
//using (MemoryStream stream = new MemoryStream (docxFile))
using (MemoryStream stream = new MemoryStream ())
{
stream.Write (docxFile, 0, docxFile.Length);
stream.Position = 0;
using (WordprocessingDocument docx = WordprocessingDocument.Open (stream, true))
{
[....]
Cheers