why can't I remove a row from VS2005 winforms grid readWrite entity collection?

Posts   
1  /  2  /  3
 
    
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 09-Dec-2006 20:03:18   

version 1.0.2005.1 final (self-servicing) VS2005 winforms Runtime Library version: 1.0.20051.51222


hiya,

I've been away for a while so please be gentle :-) I have a VS2005 winforms datagridView that is bound to a bindingSource. This bindingSource has an entityCollection for its datasource.

This entityCollection is read WRITE:

allowEdit = true allowRemove = true

The datagridView has the following properties: allowUserToDeleteRows = true readOnly = false

Why doesn't the "UserDeletingRow" event handler fire when I select a row and hit "delete"??

I know that I need a UOW inside this handler, but obviously no code will execute until I get the handler to kick in.

many thanks for any help.

yogi

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 10-Dec-2006 06:24:13   

yogi, I'm not a guru on WinForms - is it because of the BindingSource? I've never used one and in my own example to try to reproduce your issue my event handler fires just fine, but I'm not using a BindingSource.

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 10-Dec-2006 14:52:06   

thanks,

OK then, should you be able to delete rows from a datagridView if it' bound to a bindingSource?Has anyone done this?

I can't seem to get it work.

many thanks,

yogi

Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 10-Dec-2006 20:25:58   

The MSDN docs say that a binding source is supposed to allow you to change a DataSource without the grid freaking out. So I don't see why you couldn't delete rows when bound to one. Hopefully someone else out there can confirm?

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 11-Dec-2006 15:31:06   

hiya, Well, can anyone confirm?

cheers,

yogi

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 11-Dec-2006 22:38:40   

hiya,

No-one? I thought that I had asked a really concise question? The bindingSource is bound to a readWrite entityCollection.

I can confirm that I can "edit" and save the new value of a column within the datagridView. So, that pretty much confirms that the bindingSource is readWRITE.

Why, why oh why (when I'm using the SAME datagridView) doesn't the "UserDeletingRow" event fire when I select a row and press "delete"???????????

Surely someone must know?

cheers,

yogi

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 12-Dec-2006 03:15:21   

I know this doesn't help, but I did just what you explained and it worked for me.

I added the grid, then the bindingsource, then the collection. I then fill the collection on Form_Load. Then I hit delete and

private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e) { MessageBox.Show("Delete"); }

is called.

Could you post more of your code?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 10:34:46   

yogiberr wrote:

hiya,

No-one? I thought that I had asked a really concise question?

Please be patient, you'll get an answer within 24 hours regularly. You got an answer within 12 hours, which is faster than most other software vendors do. We try the best we can to help you a.s.a.p. as you know. simple_smile

The bindingSource is bound to a readWrite entityCollection.

I can confirm that I can "edit" and save the new value of a column within the datagridView. So, that pretty much confirms that the bindingSource is readWRITE.

Why, why oh why (when I'm using the SAME datagridView) doesn't the "UserDeletingRow" event fire when I select a row and press "delete"???????????

Surely someone must know?

First of all: implement the test handler BClubb suggested and see if that even gets called. If not, something else is going on. If it gets called, please update the to the latest runtime libraries for 1.0.2005.1, as 051222 is rather old, there's a newer build available for 1.0.2005.1

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 12-Dec-2006 12:38:38   

hiya,

right, sorry about the impatience :-0

Ok, I was able to use Brian's advice and create a datagridView that fired the UserDeletingRow ...

happy days, because it is in the same winforms that is giving me hassles.

However, when I use the "original" bindingSource for the datgridView, it doesn't fire. :-(

Before I post code, can anyone tell me how to get the "1.0.2005.1" runtime libraries?I can't seem to see them on the site

I might as well clean up before I post again.

many thanks,

yogi

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 13:20:08   

You have to login to the customer area, using your customerid + password, then click at the left on 1.0.2005.1 to go to the 1.0.2005.1 related downloads simple_smile . As you're using a rather old runtime, I suggest to download the latest installer for 1.0.2005.1 so you also get updated templates so everything works in sync.

It might be an event-related problem internally which has been fixed, so to be sure we're not chasing already fixed issues, I'd like to ask you to get the latest build of 1.0.2005.1 so we can exclude that it is fixed by a later build simple_smile (as it's an event related matter, it's not always easy to say the issue is fixed by looking at the changelog of 1.0.2005.1, as events often affect other things internally as well).

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 12-Dec-2006 13:39:16   

I'll give it a go.

Do I simply uninstall the previous version before running the MSI?

ta,

yogi

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 14:54:10   

Yes simple_smile

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 12-Dec-2006 16:15:28   

cheers,

OK, the runtime update was successful:


version 1.0.2005.1 final (self-servicing) VS2005 winforms Runtime Library version: 1.0.20051.60719


However, the "UserDeletingRow" event still doesn't fire. Will I start an entirely new, more concise post?I simply want it to work, and will do whatever is best to resolve asap.

So, a new post, or should I continue in this one?

ta,

yogi

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 16:43:45   

You can continue with this one. It's odd the event isn't raised, as it's a normal grid event.

If you bind the collection directly to the grid, do you see the same results? I'll also try to repro it. (btw, in google groups I found a person which had the same issue as you with the datagridview (and normal code, no llblgen pro ) and experienced this with 1 row in the grid. Is this your situation too? )

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 12-Dec-2006 17:57:55   

hiya,

<<If you bind the collection directly to the grid, do you see the same results>>

If you mean, does the "UserDeletingRow" event fire if I bind directly to the collection? ... then yes.

Unfortunately, I can't bind directly to the collection becasue I need addtional data from related tables.

I can also confirm that, EVEN when bound to the bindingSource, I am able to edit the datagridview and persist the changes..It is the "UserDeletingRow" event that is my hassle...everything else seems fine.

<<I found a person which had the same issue as you with the datagridview >>

Yes, I think I saw that as well.I emailed him but he didn't get back to m :-0

So, in light of the above, what code would you like? I could narrow it down to:

1) about 400 lines of code in a single form win app. 2) the llblgenPro DAL dll 3) sqlServer .mdf that contains 4 relevant tables.

Or, should I post it here?

cheers,

yogi

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 19:08:09   

That's not necessary. I think I can repro it myself as well. Bind with bindingsource, hit del simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 12-Dec-2006 19:59:55   

I can't reproduce it.

I've added to a form: datagridview orderdetailscollection bindingsource

I've set AllowRemove to true on the orderdetailscollection I've bound 2 event handlers to the grid: one for deleting row and one for deleted row (see code below).

Note: I fill the collection added to the form, this is essential, as I have set the allowremove property on THAT collection to true.

Anyway, it works here... so why it doesn't work in your application is a mistery to me...


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using NWTest.HelperClasses;

namespace Tester
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();


        }

        private void button1_Click(object sender, EventArgs e)
        {
            orderDetailsCollection1.GetMulti((OrderDetailsFields.OrderId == 10254));
        }

        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show("AllowRemove on bindingsource: " + bindingSource1.AllowRemove.ToString());
        }

        private void dataGridView1_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            MessageBox.Show("DeletingRow");
        }

        private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            MessageBox.Show("DeletedRow");
        }
    }
}

form:


namespace Tester
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if(disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.orderDetailsCollection1 = new NWTest.CollectionClasses.OrderDetailsCollection();
            this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
            this.orderIdDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.productIdDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.unitPriceDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.quantityDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.discountDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
            this.SuspendLayout();
            // 
            // dataGridView1
            // 
            this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.dataGridView1.AutoGenerateColumns = false;
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.orderIdDataGridViewTextBoxColumn,
            this.productIdDataGridViewTextBoxColumn,
            this.unitPriceDataGridViewTextBoxColumn,
            this.quantityDataGridViewTextBoxColumn,
            this.discountDataGridViewTextBoxColumn});
            this.dataGridView1.DataSource = this.bindingSource1;
            this.dataGridView1.Location = new System.Drawing.Point(13, 13);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(802, 482);
            this.dataGridView1.TabIndex = 0;
            this.dataGridView1.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.dataGridView1_UserDeletingRow);
            this.dataGridView1.UserDeletedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dataGridView1_UserDeletedRow);
            // 
            // orderDetailsCollection1
            // 
            this.orderDetailsCollection1.ActiveContext = null;
            this.orderDetailsCollection1.AllowEdit = true;
            this.orderDetailsCollection1.AllowNew = true;
            this.orderDetailsCollection1.AllowRemove = true;
            this.orderDetailsCollection1.Capacity = 0;
            this.orderDetailsCollection1.ConcurrencyPredicateFactoryToUse = null;
            this.orderDetailsCollection1.DoNotPerformAddIfPresent = true;
            this.orderDetailsCollection1.EntityFactoryToUse = new NWTest.FactoryClasses.OrderDetailsEntityFactory();
            this.orderDetailsCollection1.EntityValidatorToUse = null;
            this.orderDetailsCollection1.MaxNumberOfItemsToReturn = ((long)(0));
            this.orderDetailsCollection1.SortClauses = null;
            this.orderDetailsCollection1.SupportsSorting = false;
            this.orderDetailsCollection1.SuppressClearInGetMulti = false;
            this.orderDetailsCollection1.Transaction = null;
            this.orderDetailsCollection1.ValidatorToUse = null;
            // 
            // bindingSource1
            // 
            this.bindingSource1.DataSource = this.orderDetailsCollection1;
            // 
            // orderIdDataGridViewTextBoxColumn
            // 
            this.orderIdDataGridViewTextBoxColumn.DataPropertyName = "OrderId";
            this.orderIdDataGridViewTextBoxColumn.HeaderText = "OrderId";
            this.orderIdDataGridViewTextBoxColumn.Name = "orderIdDataGridViewTextBoxColumn";
            // 
            // productIdDataGridViewTextBoxColumn
            // 
            this.productIdDataGridViewTextBoxColumn.DataPropertyName = "ProductId";
            this.productIdDataGridViewTextBoxColumn.HeaderText = "ProductId";
            this.productIdDataGridViewTextBoxColumn.Name = "productIdDataGridViewTextBoxColumn";
            // 
            // unitPriceDataGridViewTextBoxColumn
            // 
            this.unitPriceDataGridViewTextBoxColumn.DataPropertyName = "UnitPrice";
            this.unitPriceDataGridViewTextBoxColumn.HeaderText = "UnitPrice";
            this.unitPriceDataGridViewTextBoxColumn.Name = "unitPriceDataGridViewTextBoxColumn";
            // 
            // quantityDataGridViewTextBoxColumn
            // 
            this.quantityDataGridViewTextBoxColumn.DataPropertyName = "Quantity";
            this.quantityDataGridViewTextBoxColumn.HeaderText = "Quantity";
            this.quantityDataGridViewTextBoxColumn.Name = "quantityDataGridViewTextBoxColumn";
            // 
            // discountDataGridViewTextBoxColumn
            // 
            this.discountDataGridViewTextBoxColumn.DataPropertyName = "Discount";
            this.discountDataGridViewTextBoxColumn.HeaderText = "Discount";
            this.discountDataGridViewTextBoxColumn.Name = "discountDataGridViewTextBoxColumn";
            // 
            // button1
            // 
            this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
            this.button1.Location = new System.Drawing.Point(13, 512);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 1;
            this.button1.Text = "Fetch";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(136, 511);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 2;
            this.button2.Text = "button2";
            this.button2.UseVisualStyleBackColor = true;
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(827, 547);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Controls.Add(this.dataGridView1);
            this.Name = "Form1";
            this.Text = "Form1";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.DataGridViewTextBoxColumn orderIdDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn productIdDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn unitPriceDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn quantityDataGridViewTextBoxColumn;
        private System.Windows.Forms.DataGridViewTextBoxColumn discountDataGridViewTextBoxColumn;
        private System.Windows.Forms.BindingSource bindingSource1;
        private NWTest.CollectionClasses.OrderDetailsCollection orderDetailsCollection1;
        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
    }
}

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 13-Dec-2006 17:41:40   

hiya,

OK, I can post the snippets of the "Designer.cs", but first, I'd like to show you this, in the hope that we can solve it without having to do that.

The datagridView is named dgvDeliveryProducts



 dgvDeliveryProducts.DataSource = this.tblAddedDeliveryProductsBindingSource;



<FORMDesigner.cs>
// tblAddedDeliveryProductsBindingSource
            // 
            this.tblAddedDeliveryProductsBindingSource.DataMember = "TblDeliveryProducts";
            this.tblAddedDeliveryProductsBindingSource.DataSource = this.BindingSourceTblDelivery;
            // 
            // BindingSourceTblDelivery
            // 
            this.BindingSourceTblDelivery.DataSource = this.currDeliveriesX;
            // 
            // currDeliveriesX
            // 
            this.currDeliveriesX.ActiveContext = null;
            this.currDeliveriesX.AllowEdit = true;
            this.currDeliveriesX.AllowNew = true;
            this.currDeliveriesX.AllowRemove = true;
            this.currDeliveriesX.Capacity = 4;
            this.currDeliveriesX.ConcurrencyPredicateFactoryToUse = null;
            this.currDeliveriesX.DoNotPerformAddIfPresent = true;
            this.currDeliveriesX.EntityFactoryToUse = new dalExpressZaxSnax.FactoryClasses.TblDeliveryEntityFactory();
            this.currDeliveriesX.EntityValidatorToUse = null;
            this.currDeliveriesX.MaxNumberOfItemsToReturn = ((long)(0));
            this.currDeliveriesX.SortClauses = null;
            this.currDeliveriesX.SupportsSorting = true;
            this.currDeliveriesX.SuppressClearInGetMulti = true;
            this.currDeliveriesX.Transaction = null;
            this.currDeliveriesX.ValidatorToUse = null;
<FORMDesigner.cs>




Below is code that displays the fact that , in the form code, tblAddedDeliveryProductsBindingSource.AllowRemove = FALSE, God knows why.




  MessageBox.Show("AllowRemove on CurrDeliveriesX: " + currDeliveriesX.AllowRemove.ToString());  //TRUE

            MessageBox.Show("AllowRemove on BindingSourceTblDelivery: " + BindingSourceTblDelivery.AllowRemove.ToString());   //TRUE
                        
            MessageBox.Show("AllowRemove on bindingsource: " + tblAddedDeliveryProductsBindingSource.AllowRemove.ToString());   //FALSE



Any ideas? I can of course include more code, but I wanted to post bare minimum to reduce hassle for people who want to help.

cheers,

yogi stuck_out_tongue_winking_eye

yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 14-Dec-2006 10:56:26   

hiya,

ok, I now know WHERE the problem is, but not why.

I get the error because "tblAddedDeliveryProductsBindingSource" has a dataMember..If i remove the dataMemeber, I AM able to remove rows.

Of course if I remove the tblAddedDeliveryProductsBindingSource.dataMember then my datagridView does not contain the correct fields.

Does anyone have any idea what I can do?

ta,

yogi

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 14-Dec-2006 12:06:22   

Hmm... I think I can explain this. You actually bind TblDeliveryProducts, do you set the AllowREmove on THAT collection to true? I think you set the allowremove on the parent collection, or am I mistaken?

Frans Bouma | Lead developer LLBLGen Pro
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 14-Dec-2006 13:09:56   

hiya,

Ok, how do I set the AllowREmove on "TblDeliveryProducts" collection to true?

"TblDeliveryProducts" is the a dataMember of tblAddedDeliveryProductsBindingSource.



tblAddedDeliveryProductsBindingSource.datamember = TblDeliveryProducts
                                    
tblAddedDeliveryProductsBindingSource,datasource = BindingSourceTblDelivery

as such, "TblDeliveryProducts" does not appear in the properties section of the IDE, how can I set it?

cheers,

yogi

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 14-Dec-2006 14:37:29   

Set it programatically:


TblDeliveryProducts.AllowRemove = TRUE
tblAddedDeliveryProductsBindingSource.datamember = TblDeliveryProducts
tblAddedDeliveryProductsBindingSource,datasource = BindingSourceTblDelivery
yogiberr
User
Posts: 432
Joined: 29-Jun-2005
# Posted on: 14-Dec-2006 15:03:58   

once again, HOW?

if I do the following:


 TblDeliveryProductsCollection TblDeliveryProducts = new TblDeliveryProductsCollection();

TblDeliveryProducts.AllowRemove = true;
tblAddedDeliveryProductsBindingSource.DataMember = "TblDeliveryProducts";
tblAddedDeliveryProductsBindingSource.DataSource = BindingSourceTblDelivery;        


Then it still doesn't work.My guess is that creating a new intstance of "TblDeliveryProductsCollection " which I happen to name "TblDeliveryProducts", isn't going to help.How can I assign this instance of entityCollection as a "dataMember??

I THINK need to be able to assign the "datamember" property of tblAddedDeliveryProductsBindingSource to the instance of "TblDeliveryProductsCollection".....

Something along the lines of:



tblAddedDeliveryProductsBindingSource.DataMember = TblDeliveryProducts?????


I'm nearly there i hope,

please help,

ta.

yogi

Walaa avatar
Walaa
Support Team
Posts: 14993
Joined: 21-Aug-2005
# Posted on: 14-Dec-2006 15:28:24   

I'm lost between all those elements.

I assume that you have a control, a binding source and a collection "MainCollection". are you trying to bind to a related collection "MainEntity.SubCollection." ?

You can loop on the entities of your main entity and set the SubCollection.AllowRemove of each.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39833
Joined: 17-Aug-2003
# Posted on: 14-Dec-2006 15:57:58   

I think it can be done simpler, by binding to the event in the master grid or something, where the active row is changed, so at that spot the parent entity is known and you can set the child collection's AllowRemove to true.

Frans Bouma | Lead developer LLBLGen Pro
1  /  2  /  3