fbpx
Welcome, Guest
Username: Password: Remember me
Visual Objects

Please use this forum to post questions about Visual Objects and Vulcan.NET

TOPIC:

OK you've finally got me, X# is very cool! 19 Mar 2019 09:27 #7842

  • hsc's Avatar

  • hsc


  • Posts: 126
  • Hi All

    in a visit to chris's post I wrote a similar application for comparison, without using VO, It's written in a core dialect. I replaced DBserver
    with OleDB.

    Juraj
    Attachments:

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 19 Mar 2019 09:32 #7843

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Chris,

    just to be clear for anybody else reading this thread, this is only ONE of the ways of how things work in X#.


    thank you for your clarification! Sometimes, if you are asking 5 programmers for the solution of a problem, you will get at least 20 different solutions <g>.

    I would like to include also this in the XIDE samples if you do not mind.


    Of course you can do this! I'll send you an extended version of it later today.

    Wolfgang

    P.S. sometimes it would be very helpful to create a VS project or solution from an XIDE application, so even VS users could use it
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 19 Mar 2019 10:30 #7846

  • Chris's Avatar

  • Chris


  • Posts: 2039
  • OK, thanks!

    About creating a VS solution, well the reason why I used my own format, was because I couldn't stand the VS project system, so I am really not looking forward to understand it and write code to utilize it/save in this format. But of course you are very welcome to write a plugin that does that if you like :)
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 19 Mar 2019 10:44 #7847

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Chris,

    the XPorter/VO creates a VS solution already, so you have the code.... I would have to reverse engineer the needed files.
    If you can give me the code how you create a VS project, I will build the plugin <g>

    Wolfgang

    P.S. I remembered I had the source to the Xporter somewhere, and in fact, I have an old version of it, so I could take this as sample, if you agree
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 19 Mar 2019 11:30 #7849

  • Chris's Avatar

  • Chris


  • Posts: 2039
  • Hi Wolfgang,

    Please have a look at your \XSharp\VOXPorter\Templates folder, and open the file template_VS.xsproj. As you will see, this is an already existing VS project file (I just created a new test project in VS and copied the project file), it just has a few wholes for inserting the files and references created by VOXPorter, which uses this file as a template.

    So, no, I do not have code for creating a VS project file, only some very simple one to insert files and references. And even for that, I have simply hard coded inside the VOXporter the text that VS expects, just copied it again from an existing project file :)

    You can find the complete VOXporter code here: github.com/X-Sharp/XSharpPublic/tree/fea...time/Tools/VOXporter
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 19 Mar 2019 11:34 #7850

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Chris,

    thank you very much! I will do that.

    I have only too limited time to dedicate it to reverse engineering of the VS project files.

    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 00:41 #7918

  • FoxProMatt's Avatar

  • FoxProMatt


  • Posts: 400
  • Wolfgang -

    Thanks for the sample app and data. I was able to get the app running from XIDE and the DBFs.

    Attachments:

    Please Log in or Create an account to join the conversation.

    Last edit: by FoxProMatt.

    OK you've finally got me, X# is very cool! 23 Mar 2019 01:01 #7919

  • FoxProMatt's Avatar

  • FoxProMatt


  • Posts: 400
  • Wolfgang -

    I have studied this code, and while I can say as a VFP and C# coder, new to X#, it is indeed easy to follow what the code is doing, *however*, that sure is a LOT of code to get data from a DBF. You went to a DataTable, which I think is a .Net thing, right? In VFP we just say:
    USE SomeTable.DBF Alias MyData
    Grid.Recordsource = "MyData"

    This code sample iterates over every column in the table and every row in the table to build a DataTable, which is probably disconnected from the original DBF where the data came from.

    So what paradigm am I missing, where I desire to bind a UI grid directly to a live DBF, or a cursor from a SQL Query?

    Static Method GetCustomerTable() As DataTable
    	Local oCustomer		As DataTable
    	Local oServer		As DBServer
    	Local nField		As Int
    	Local nFCount		As Int
    	Local aFields		As Array
    	Local cFieldName	As String
    	Local oRow			As DataRow
    
    	oCustomer			:= DataTable{ "Customer" }
    	oServer				:= DBServer{ System.IO.Path.Combine( ProgSettings.DataPath, "Customer.dbf" ), True, True, ProgSettings.DefaultRDD }
    	oServer:SetOrder( "Cust1.ntx" )
    	oServer:GoTop()
    	nFCount				:= oServer:FCount
    	aFields				:= ArrayNew( nFCount )
    	For nField := 1 UpTo nFCount
    		cFieldName			:= Proper( oServer:FieldName( nField ) )
    		aFields[nField]		:= cFieldName
    		oCustomer:Columns:Add( cFieldName, System.Type.GetType( "System.String" ) )
    	Next
    
    	While ! oServer:EOF
    		oRow				:= oCustomer:NewRow()
    		For nField := 1 UpTo nFCount
    			cFieldName			:= aFields[nField]
    			If IsString( oServer:FieldGet( nField ) )
    				oRow[cFieldName]	:= AllTrim( oServer:FieldGet( nField ) )
    			Else
    				oRow[cFieldName]	:= AsString( oServer:FieldGet( nField ) )
    			EndIf
    		Next
    		oCustomer:Rows:Add( oRow )
    		oServer:Skip()
    	End
    	oServer:Close()
    
    	Return oCustomer

    Please Log in or Create an account to join the conversation.

    Last edit: by FoxProMatt.

    OK you've finally got me, X# is very cool! 23 Mar 2019 05:08 #7922

  • lumberjack's Avatar

  • lumberjack


  • Posts: 687
  • Matt,
    Yes that is a "hardcoded" approach for a specific customer table.
    However, here is the beauty of X#. XSharpPublic contain the runtime source code. I will push a function DbDataTable soon and also have this feature in the OOP implementation DbServer.

    Code will change to:
    USE SomeTable.DBF ALIAS Alias
    oGrid:DataSource := DbDataTable()
    Or:
    oCust :=  DbServer{<pars>, "SomeTable.DBF", <pars,...>, "Alias"}
    oGrid:DataSource := oCust:DataTable()
    Just remember there are very few people coming from VO that use the COMMAND/Functional DBF approach these days, most are using the OOP implementation.

    Hope this satisfy your concern,
    ______________________
    Johan Nel
    George, South Africa

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 06:46 #7925

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Matt,

    that sure is a LOT of code to get data from a DBF.

    yes, you are right about this.
    But my code (one static function) is a connection between two worlds: the DBServer as VO data object to the .NET datatable.
    Therefore it needs some connection code.
    And if you look at my code, you see that there is no assumption of a data structure, and there could be one static function that takes a filename and returns a datatable - in fact my code is written so it is generalized.
    If the DBServer would be understand SQL statements as the relative object in VFP does, it could be written in a select statement.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 08:35 #7927

  • FoxProMatt's Avatar

  • FoxProMatt


  • Posts: 400
  • Johan and Wolfgang -

    I think it's important to remember that there are *two* distinct ways that each code sample must be reviewed, discussed, considered:

    -> One is that it's a code example written to demonstrate what is a possible in X#, or perhaps even a best practice to get the most out of it when you have the luxury of writing new code.

    -> The other is code that is presented as an example of what needs to be supported if there is hope of getting VFP people to use X# by way of porting their app code pretty much exactly the way it is written right now, and has been been written and maintained for many years.

    There are lots of VFP people who have indeed used the old style XBase COMMAND/Functional DBF approach, and if they saw that VO/OO/Data Table code in Wolfang's example, their mind would be blown and they'll think they've landed on another planet.

    I love the OO world and disconnected data, and all that. My VFP app is written with lots of those paradigms because I know it from 10 years of C# and Ruby on Rails and other Non-VFP exposure, but not all VFP people have had that luxury (or desire) and I just want to make sure that I demonstrate and discuss many of those XBase COMMAND/Functional DBF patters to the X# team and the FOX users so they see what is *required* to be supported in X# in order to on-board VFP apps written in that older style.

    If there becomes a VFP Transporter tool that can scrape an entire app from an existing VFP code project, it will results in lots of XBase COMMAND/Functional DBF code patterns that will need to be supported.

    Even if a magic VFP Transporter could do incredible transformations of their existing old-style code patterns into new X# paradigms, we still have to realize we'd be giving them a new fancy code base, but it would be one they won't understand.

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 10:16 #7930

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Matt,
    my sample was written for a specific request: for a VO programmer that would see how the VO specific data access could be bound to the .NET specific GUI.
    Of course, VFP programmers need other samples, but infortunately I have not used commands for about 20 years now, so I'm not very used with them.
    Personally, I think even people that uses the command/functional approach should adopt the OOP approach as fast as possible, not because I think it is the better approach (and yes, I'm convinced that software without OOP is much harder to maintain and to extend), but because the entire .NET Framework is built in classes.
    For sure, for migrating code the compiler needs to be enhanced, and runtime libraries written, but in the long run only the use of the .NET Framework will justify the migration work.
    Wolfgang
    P.S. I will try to build another version of the sample for VFP programmers - or you could change it to make it easier to understand. Feel free to take the code, change it and publish it here or somewhere!
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 11:14 #7934

  • FoxProMatt's Avatar

  • FoxProMatt


  • Posts: 400
  • Wolfgang -

    I don’t yet know enough about X# myself to be writing samples or converting existing code.

    It could lead to a confusing, and bad example.

    But I’d love to see it converted, and I’m sure I’d learn a lot from it. And I could give feedback from a FoxPro dev perspective.

    Please Log in or Create an account to join the conversation.

    Last edit: by FoxProMatt.

    OK you've finally got me, X# is very cool! 23 Mar 2019 16:25 #7936

  • Chris's Avatar

  • Chris


  • Posts: 2039
  • Hi Matt,

    In VFP, you can do a simple

    USE SomeTable.DBF Alias MyData
    Grid.Recordsource = "MyData"

    because, under the hood, this translates to (or, to be more correct, makes a call to) A LOT of code that has already been written by the VFP creators, in order to support this. Similar in VO, you can do the same thing as in VFP, people can easily do a very simple

    LOCAL oCustomers := CusomerDataServer{}
    oDataBrowser:Use(oCustomers)

    which again calls a function that contains a lot of already written code (in the VO GUI and RDD classes) to take care of all the rest.

    For VO programmers, all this code of the VO base classes has been ported to .Net, so people can use their existing code with no changes, they can still use "oDataBrowser:Use(oCustomers)" exactly as before, if they chose to continue using this way of doing this (which is a very good idea, especially when you consider apps with 100,000s or millions of lines of code...). Same goes for VFP, in order to properly support people with existing apps to port them to .Net/X#, we need to provide them with the equivalent of the framework you are using in VFP, now compiled in X#, running under .Net. That's the main part of the process for supporting VFP in X# that is gonna take the most effort.

    About Wolfgang's code, if you are gonna use this approach, then of course you will not be rewriting the same code over and over again! That was just a sample on how to do this (DBF with DataTables), but if you're gonna use this extensively in an app, you would put all that code in just one function, declare it in a library, and then use only 2-3 lines of code in your actual app code, simply calling that functions. Exactly the same way as Grid.Recordsource = "MyData" and oDataBrowser:Use(oCustomers) already work.
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    OK you've finally got me, X# is very cool! 23 Mar 2019 17:58 #7938

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Matt,

    please look at this code to build the DataTable:
    static method GetCustomerTableFunction() as DataTable
    // creates a .NET DataTable from the DBF data
    local oCustomer as DataTable
    local nField as dword
    local nFCount as dword
    local aFields as array
    local cFieldName as string
    local oRow as DataRow
    local cTableName as string
    
    cTableName := "Customer"
    // create the DataTable
    oCustomer			:= DataTable{ cTableName }
    // open the DBServer readonly and shared
    if DBUseArea( true, ProgSettings.DefaultRDD, System.IO.Path.Combine( ProgSettings.DataPath, "Customer.dbf" ), cTableName, true, true )
      DBSetOrder( "Cust1.ntx" )
      DBGoTop()
      // build the DataTable field structure, only string fields to keep thing simple
      nFCount := FCount()
      aFields := ArrayNew( nFCount )
      for nField := 1 upto nFCount
        cFieldName := Proper( FieldName( nField ) )
        aFields[nField] := cFieldName
        oCustomer:Columns:Add( cFieldName, System.Type.GetType( "System.String" ) )
      next
      // fill the DataTable with the DBF data
      while ! EOF()
        oRow := oCustomer:NewRow()
        for nField := 1 upto nFCount
          cFieldName := aFields[nField]
          if IsString( FieldGet( nField ) )	// convert to string if needed
            oRow[cFieldName] := AllTrim( FieldGet( nField ) )
         else
            oRow[cFieldName]	:= AsString( FieldGet( nField ) )
         endif
         next
         oCustomer:Rows:Add( oRow )
         DBSkip()
      end
    // and close the DBF file
      DBCloseArea()
    endif
    
    return oCustomer

    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 18:16 #7939

  • wriedmann's Avatar

  • wriedmann


  • Posts: 2300
  • Hi Matt,

    please let me add that I would never write my code that way, because in a WIndows application nobody can make sure that this alias is not already used in another window or process. Therefore I had the build an unique alias first, before calling the DBUseArea() function.
    I don't know how VFP handles these situations....
    And there is another risk in a WIndows application: if somewhere in the reading loop is added a waitstate that transfers execution time to another process: nobody can exclude that the current active workarea is changed and the function gives unexpected results.
    The VO DBServer class handles all these situations internally, and if I had not such a class already in the framework, I would build one.
    But as I wrote: I don't know VFP and therefore I suspect it handles such things in another way.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 19:38 #7947

  • FoxProMatt's Avatar

  • FoxProMatt


  • Posts: 400
  • Chris wrote:

    ...especially when you consider apps with 100,000s or millions of lines of code...). Same goes for VFP, in order to properly support people with existing apps to port them to .Net/X#, we need to provide them with the equivalent of the framework you are using in VFP, now compiled in X#, running under .Net. That's the main part of the process for supporting VFP in X# that is gonna take the most effort.


    Yes, yes, this is the part I am looking for if there is any hope for widespread FoxPro adoption. People are going to want their code to just magically run, with very little changes.

    Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.
    Select 0
    Use Customers Order id
    
    Select 0
    Use Orders
    Set Relation To Customer_id into Customers
    
    Scan
    
    	? Orders.OrderNo " from " + Customers.Name
    
    EndScan

    Once you have this type of VFP commands working in X# in Visual Studio, I think you can turn a lot of heads.

    Here's what I'd consider a basic VFP command list that, when working in X#/VS, you'll attract *A LOT* of VFP lookers:
    SELECT
    USE
    SET ORDER
    SET RELATION
    INDEX
    LOCATE
    REPLACE
    SCAN/ENDSCAN
    STORE

    Next, FoxPro SQL command set (direct language commands against DBF Tables and Cursors, not SQL Strings sent to ODBC server)
    SELECT, INSERT, UPDATE, DELETE

    Please Log in or Create an account to join the conversation.

    Last edit: by FoxProMatt.

    OK you've finally got me, X# is very cool! 23 Mar 2019 19:52 #7949

  • Chris's Avatar

  • Chris


  • Posts: 2039
  • Matt,

    This is exactly what happened with VO, existing VO code "magically" runs now in X#! Of course there was no magic behind it, it is that we worked very hard to make the underlying VO classes compile under .Net and behave exactly the same way as they do in VO.

    Something similar needs to be done about VFP, too. Obviously this is not a trivial task and of course we will need a lot of help from the VFP community and everybody else like Johan or anybody else who is interested in producing this. It will either involve compiling the underlying VFP system code in X#, or building a set of classes (with the same names, properties, functions etc as in VFP) which emulates the exact same behavior under .Net, using standard .Net classes. Or a combination of the two!
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    OK you've finally got me, X# is very cool! 23 Mar 2019 19:55 #7950

  • Chris's Avatar

  • Chris


  • Posts: 2039
  • mattslay wrote: Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.

    Select 0
    Use Customers Order id
    
    Select 0
    Use Orders
    Set Relation To Customer_id into Customers
    
    Scan
    
    	? Orders.OrderNo " from " + Customers.Name
    
    EndScan

    Once you have this type of VFP commands working in X# in Visual Studio, I think you can turn a lot of heads.

    Here's what I'd consider a basic VFP command list that, when working in X#/VS, you'll attract *A LOT* of VFP lookers:
    SELECT
    USE
    SET ORDER
    SET RELATION
    INDEX
    LOCATE
    REPLACE
    SCAN/ENDSCAN
    STORE


    That's the easy part, isn't that already working?


    mattslay wrote: Next, FoxPro SQL command set (direct language commands against DBF Tables and Cursors, not SQL Strings sent to ODBC server)


    That's the more difficult part :)
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    Last edit: by Chris.

    OK you've finally got me, X# is very cool! 24 Mar 2019 08:02 #7955

  • Karl-Heinz's Avatar

  • Karl-Heinz


  • Posts: 585
  • Chris wrote:

    mattslay wrote: Here's a basic old style code sample that needs to run as-is under X# before anything is presented to the VFP community.

    Select 0
    Use Customers Order id
    
    Select 0
    Use Orders
    Set Relation To Customer_id into Customers
    
    Scan
    
    	? Orders.OrderNo " from " + Customers.Name
    
    EndScan
    SELECT
    USE
    SET ORDER
    SET RELATION
    INDEX
    LOCATE
    REPLACE
    SCAN/ENDSCAN
    STORE


    That's the easy part, isn't that already working?


    Hi Chris,

    on GitHub i´ve found the UDC file dbcmd.xh . Wouldn´t it make sense to add it to the XSharp setup and install it in the \include dir ?

    github.com/X-Sharp/XSharpPublic/blob/a13...bd2b/Common/dbcmd.xh

    regards
    Karl-Heinz

    Please Log in or Create an account to join the conversation.