I have a problem with making the mainwindow on my simple app run, The error given is that - Object reference not set to an instance of an object.
this happens when the app is getting debugged and the error occurs at handler.window1.ShowAll()
I did find some code online which hints at adding some member code as in member this.Whatever() = window1 however i have no idea if this is relevent to my code, or where to put it.
i am happy for any help you can give me as i have been trying all day to get this working in many ways and simply cannot.
namespace potato
module Main =
open System
open Gtk
type Handler()=class
[<Object>]
[<DefaultValue(true)>]
val mutable window1 : Window
end
[<EntryPoint>]
let Main(args) =
Application.Init()
let builder = new Builder("GUI.ui")
let handler = new Handler()
builder.Autoconnect(handler)
handler.window1.ShowAll()
Application.Run()
0
Here is the glade.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.18"/>
<object class="GtkWindow" id="window1">
<property name="width_request">1024</property>
<property name="height_request">576</property>
<property name="can_focus">False</property>
<child>
<placeholder/>
</child>
</object>
</interface>
Right, the problem was right in front of my eyes, and i ended up having to go through old test projects to see and realise what #scrwtp was hinting at, this is the old working code fixed for gtk3 gtkbuilder.
namespace potato
module Main =
open System
open Gtk
type Handler()=class
[<Builder.Object>]
[<DefaultValue(true)>]
val mutable window1 : Window
end
let OnDelete (args:DeleteEventArgs) =
Application.Quit()
args.RetVal <- true
[<EntryPoint>]
let Main (args) =
Application.Init()
let gxml = new Builder("GUI.xml")
let handler = new Handler()
do gxml.Autoconnect(handler)
handler.window1.DeleteEvent
|> Event.add OnDelete
handler.window1.ShowAll()
Application.Run()
0
The reason, i now understand is that i had specified a handler and passed nothing to it, because nothing was passed it IE:(handler.window1.DeleteEvent) it simply wouldnt show when i called showall, hope this helps someone else with a similar problem
Related
I want to parse data from my bank account in F# that are provided in XML. I have an XSD schema of a statement.
My code reads the schema but it is not able to read the structure. I see the content in XML in data.XElement, however, data.AccountStatement property does not exist. The code goes to None option and then the application crashes. Do you have any idea why the code loads the schema but cannot work with data in XML?
open FSharp.Data
let TestAddress = "TESTADDRESS"
let dateRegex = #"\d{1,2}[.]\d{1,2}[.]\d{4}";
type BankTransactionList = XmlProvider<Schema="Schemas/IBSchema.xsd">
let data = BankTransactionList.Parse(Http.RequestString(TestAddress))
[<EntryPoint>]
let main argv =
let AccountStatement =
match data.AccountStatement with
| Some v -> Some v
| None -> None //code goes here
let TransactionList =
match AccountStatement.Value.TransactionList with //and crashes here
| Some v -> Some v
| None -> None
for transaction in TransactionList.Value.Transactions do
printf "%s" transaction.Column22.Value
0 // return an integer exit code
I am developing in .Net Core 2.1. You can see the anonymized example of XML data below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccountStatement>
<Info>
<accountId>X</accountId>
<bankId>X</bankId>
<currency>CZK</currency>
<iban>X</iban>
<bic>X</bic>
<openingBalance>X</openingBalance>
<closingBalance>X</closingBalance>
<dateStart>X</dateStart>
<dateEnd>X</dateEnd>
<idFrom>X</idFrom>
<idTo>16663326563</idTo>
</Info>
<TransactionList>
<Transaction>
<column_22 name="ID pohybu" id="22">0</column_22>
<column_0 name="Datum" id="0">2018-08-25+02:00</column_0>
<column_1 name="Objem" id="1">0</column_1>
<column_14 name="Měna" id="14">CZK</column_14>
<column_5 name="VS" id="5">1023</column_5>
<column_16 name="Zpráva pro příjemce" id="16">Message</column_16>
<column_8 name="Typ" id="8">Platba kartou</column_8>
<column_9 name="Provedl" id="9">Pešík, Jiří</column_9>
<column_17 name="ID pokynu" id="17">0</column_17>
</Transaction>
</TransactionList>
</AccountStatement>
I think the issue is that the schema requires the namespace: "http://www.fio.cz/IBSchema".
Adding the namespace in the document should solve the issue:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AccountStatement xmlns="http://www.fio.cz/IBSchema">
<Info>
<accountId>X</accountId>
<bankId>X</bankId>
<currency>CZK</currency>
<iban>X</iban>
<bic>X</bic>
<openingBalance>0</openingBalance>
<closingBalance>0</closingBalance>
<dateStart>2000-01-01</dateStart>
<dateEnd>2001-01-01</dateEnd>
<idFrom>0</idFrom>
<idTo>16663326563</idTo>
</Info>
<TransactionList>
<Transaction>
<column_22 name="ID pohybu" id="22">0</column_22>
<column_0 name="Datum" id="0">2018-08-25+02:00</column_0>
<column_1 name="Objem" id="1">0</column_1>
<column_14 name="Měna" id="14">CZK</column_14>
<column_5 name="VS" id="5">1023</column_5>
<column_16 name="Zpráva pro příjemce" id="16">Message</column_16>
<column_8 name="Typ" id="8">Platba kartou</column_8>
<column_9 name="Provedl" id="9">Pešík, Jiří</column_9>
<column_17 name="ID pokynu" id="17">0</column_17>
</Transaction>
</TransactionList>
</AccountStatement>
I hope your bank is not producing documents lacking the namespace and a schema requiring it.
I have added Report.rpt and a Report.fs file by right clicking on project in Solution Explorer. In Report.fs I have declared two Type Report() and CachedReport(), which in C# are generated automatically, and added F# code in it by looking at a .cs file which CrystalReport generated in a C# WPF Projet. In Xaml I have
<ContentControl Content="{Binding ShowReport}"/>
<Button Command="{Binding ViewReport}" Content="Click" Grid.Row="1"/>
and in ViewModel
let doc = new CrystalReportsViewer()
let setSource() =
let rpt = new Report()
rpt.Load("~/Report.rpt")
doc.ViewerCore.ReportSource <- rpt
member x.ShowReport = doc
member x.ViewReport = self.Factory.CommandSync(setSource)
When I start the application I can see CrystalReport Viewer in place. If I click the button Application closes automatically.
If I double click on Report.rpt a dialog box pops up and says This document could not be opened.
How can I use it in F# WPF?
Is there any other reporting tool for F# WPF?
I just need to build a C# Class Library with a Report as embedded resource, add the assembly in F# reference and write ...
let doc = new CrystalReportsViewer()
let setSource() =
let rpt = new MyCsClass.CrystalReport1()
....
doc.ViewerCore.ReportSource <- rpt
thats all!
How to get the xml-stylesheet using xml type provider?
let xml = XmlProvider<"""<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type='text/xsl' href='/stylesheets/application_internet.xsl'?>
<application>......</application>""").GetSample()
let stylesheetHref = xml.....?
Expect string '/stylesheets/application_internet.xsl'.
There is no easy way I know of to get processing instructions and associated data using TypeProviders (or Linq to XML).
It can be done like this, though:
For your example XML GetSample returns just the root element content, i.e. ....... Changing that a bit lets us access the root XElement. Knowing the processing node is its preceding sibling, we can get a XProcessingInstruction and extract the url from its Data.
#I "../packages/FSharp.Data.2.2.5/lib/net40"
#r "System.Xml.Linq"
#r "FSharp.Data.dll"
open FSharp.Data
open System.Text.RegularExpressions
open System.Xml.Linq
let href s = Regex.Match(s, "href='(?<url>.*?)'").Groups.["url"].Value
type Xml = XmlProvider<"""<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type='text/xsl' href='/stylesheets/application_internet.xsl'?>
<application><other></other></application>""">
let doc = Xml.GetSample()
let stylesheetProcessing = (doc.XElement.PreviousNode :?> XProcessingInstruction)
// /stylesheets/application_internet.xsl
let url = href stylesheetProcessing.Data
Obviously this code expects the XML to always have a valid instruction in the same place. Adding error handling is left as an exercise :-)
I'm trying to read an ADOBD.Recordset object like this (my first time, so pardon my "noobness" :D):
Presentation.Category categorySvc = new Presentation.Category();
ADODB.Recordset categories = categorySvc.ListAll("BE", "DUE", "EN", 128);
foreach (var category in categories.Fields) // here is where I get the exception
{
// ...
}
The ListAll call works fine - I get the Recordset with some data which I confirm that by doing a QuickWatch on the object. But when the code reach the categories.Fields I get the following exception:
Could not load type
'ADODB.FieldsToInternalFieldsMarshaler'
from assembly 'TestCOMCalls,
Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
I googled this error (or just by 'ADODB.FieldsToInternalFieldsMarshaler' and couldn't find anything that would help me with issue).
I wonder, am I missing a reference? Besides the normal references I have added this one to my project:
ADODB
Microsoft ActiveX Data Objects 2.5 Library
C:\WINDOWS\assembly\GAC\ADODB\7.0.3300.0__b03f5f7f11d50a3a\ADODB.dll
Like I said, I've never done this before but by googling a bit I was able to see some people doing this (foreach on the object.Fields) and it seem to work for them.
Any help or direction is greatly appreciated :)
Thanks!
It's on the individual references - not in the project properties. In the solution explorer window, open "References" (under the project), and click on the reference in question. The properties window will have an option for Embed Interop Types (for each reference).
In Visual BAsic 2010:
To turn off Embed Interop Types:
Project menu > Show All Files, Solution Explorer: > References: > ADODB > Embed Interof types = False. Microsoft.Office.Interop.Access > Embed Interof types = False
You will now be able to publish and also ADODB will appear in the: Project Menu > Project Properties… Publish TAB > Application Files
Solved:
Solution Explorer --> Show all files (Menu Item) --> Referances --> Adodb -->(properties) -->Embed Interop Types --> False.
See what I found on this question here. I referenced yours, but still couldn't get the ADODB to work.
Little one to add:
SolutionExplorer --> View All Files.
For ADODB:
- Embed... = False;
- Copy Local = True.
Got the same problem in VS 2013, and the solution for that is that you go to
References and select ADODB, on properties you will see Embed Interof types = True then change it to false.
I got this problem clearing temporary file(VS 2017). Solution for this exception you need to change Solution Explorer > References > adodb > "Then Right click and choose properties" > Embed Interop Types, set "True" to "False"
Okay, I figured how to do this:
Presentation.Category categorySvc = new Presentation.Category();
ADODB.Recordset categories = categorySvc.ListAll("BE", "DUE", "EN", 128);
categories.MoveFirst();
while(!categories.EOF)
{
var fields = ((dynamic)categories).Fields;
for (int i = 0; i < fields.Count; i++)
{
var field = fields[i];
var name = field.Name;
var value = field.Value;
// ...
}
categories.MoveNext();
}
The CreateSpreadsheetWorkbook example method from the OpenXml documentation does translate directly to F#. The problem seems to be the Append method of the Sheets object. The code executes without error, but the resulting xlsx file is missing the inner Xml which should have been appended, and the file is unreadable by Excel. I suspect the problem stems from the conversion of functional F# structures into a System.Collections type, but I do not have direct evidence for this.
I have run similar code in C# and VB.NET (i.e. the documentation example) and it executes perfectly and creates a readable, complete xlsx file.
I know that I could deal with the XML directly, but I would like to understand the nature of the mismatch between F# and OpenXml. Any suggestions?
The code is almost directly from the example:
namespace OpenXmlLib
open System
open DocumentFormat
open DocumentFormat.OpenXml
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Spreadsheet
module OpenXmlXL =
// this function overwrites an existing file without warning!
let CreateSpreadsheetWorkbook (filepath: string) =
// Create a spreadsheet document by supplying the filepath.
// By default, AutoSave = true, Editable = true, and Type = xlsx.
let spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook)
// Add a WorkbookPart to the document.
let workbookpart = spreadsheetDocument.AddWorkbookPart()
workbookpart.Workbook <- new Workbook()
// Add a WorksheetPart to the WorkbookPart.
let worksheetPart = workbookpart.AddNewPart<WorksheetPart>()
worksheetPart.Worksheet <- new Worksheet(new SheetData())
// Add Sheets to the Workbook.
let sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets())
// Append a new worksheet and associate it with the workbook.
let sheet = new Sheet()
sheet.Id <- stringValue(spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart))
//Console.WriteLine(sheet.Id.Value)
sheet.SheetId <- UInt32Value(1u)
// Console.WriteLine(sheet.SheetId.Value)
sheet.Name <- StringValue("TestSheet")
//Console.WriteLine(sheet.Name.Value)
sheets.Append (sheet)
// Console.WriteLine("Sheets: {0}", sheets.InnerXml.ToString())
workbookpart.Workbook.Save()
spreadsheetDocument.Close()
The sheet is created, but empty:
sheet.xml:
<?xml version="1.0" encoding="utf-8" ?>
<x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />
workbook.xml:
<?xml version="1.0" encoding="utf-8" ?>
- <x:workbook xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
- <x:sheets>
<x:sheet name="TestSheet" sheetId="1" r:id="R263eb6f245a2497e" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" />
</x:sheets>
</x:workbook>
The problem is very subtle, and is in your calls to the Worksheet constructor and the Sheets.Append method. Both of these methods are overloaded, and can take either a seq<OpenXmlElement> or any number of individual OpenXmlElements (via a [<System.ParamArray>]/params array). The twist is that the OpenXmlElement type itself implements the seq<OpenXmlElement> interface.
In C#, when you call new Worksheet(new SheetData()), the compiler's overload resolution picks the second of the overloads, implicitly creating a one-element array containing the SheetData value. However, in F#, since the SheetData class implements IEnumerable<OpenXmlElement>, the first overload is chosen, which creates a new WorkSheet by enumerating the contents of the SheetData, which is not what you want.
To fix this, you need to set up your calls so that they use the other overload (first example below) or explicitly create a singleton sequence (second example below):
worksheetPart.Worksheet <- new Worksheet(new SheetData() :> OpenXmlElement)
...
sheets.Append([sheet :> OpenXmlElement])