This question has cropped up before and I thought that for convenience, I’d add a post as an anchor point.
In the Smart Office blog from our friendly Smart Office developers in Sweden, we have a post which answers the question that many of us had been asking for a long time. How to add a column to a ListView in Smart Office. As most of you know there are a number of traps and oddities around the ListView which make what you would expect to be a fairly simple task horribly complex.
http://smartofficeblog.com/2012/02/13/adding-a-new-column-in-a-m3-list/
(which is based off a great post by Thibaud here https://thibaudatwork.wordpress.com/2011/09/22/how-to-add-a-column-to-a-list/)
The one problem with this script is that it will break when you have an Editable cell in your ListView, and this is due to these two lines of code:
var newItems = new String[columnCount];
row.Items.CopyTo(newItems,0);
Specifically the creating the array as an array of strings rather than objects. The ListRow object that is bound to the ItemsSource has an array of objects – currently these can be either String objects OR Mango.UI.Services.Lists.EditableCell objects.
I used the Visual Studio debugger so I could see the objects below (I am preparing a more detailed article on how this works – it is pretty kewl what happens!)
See the Items property above – we have an array of object[19] – one object for each column. The highlighted line above shows that the 4th item in the array is not a String. So instantly an exception will get thrown when we try to copy the EditableCell in to a String.
Correcting this is remarkably simple, we change line 43 in the linked article to read like this:
var newItems = new Object[columnCount];
The CopyTo will no longer throw an exception.
Happy coding!
Cheers,
Scott
Hi Scott, there is one more thing to notice. I saw solutions where a row is updated by deleting it and creating a new row which is inserted at the old place. This way all formatting ist gone, which is extremely bad for numeric and date values. But the single cell will hold a content presenter, and its content can be updated. This way it is possible to change a single value on the screen instead of deleting /inserting the whole row. The SmartOfficeBlog contains an example where this technic is used to add a tooltip to a cell. It gave me the kick some years ago. In the same way it is possible to change the content.
After reading 3000 book pages about C# and -more important- WPF it is obvious that the topic is too complex to handle it in a trial-and-error-mode. Many of us -me too- simply didn’t know enough about the basic’s of WPF, concepts of logical and visual trees, and the WPF controls.
I encourage everyone who is not a .Net developer by profession to read a good book about WPF – and use a tool like “WPF Inspector” or similiar to analyze the structure of running WPF applications like Smart Office. It will open up your knowlegde for unlimited modifications of Smart Office.
And I want to encourage everyone to switch to C# instead of JScript. The code is nearly the same (besides a lot of type casting which JScript does in the background, this must be explicitely done in C#), but you will be able to debug your code at runtime and inspect the value and structure of the objects while the code is running, setting break points, stepping from code line to code line, changing values at runtime etc. Together with a good logging concept this will improve the Smart Office solutions dramatically. C#-dll’s are added to M3 screens in the same way as scripts and don’t require the SDK. But of course Visual Studio knowledge is required.
But VS will open us another interesting option: With VS 2013, VSTO is a part of the express version! We are now able to create Net AddIns for Excel without purchasing a “Professional” addition. This means, that Net applications could replace VBA code. VS 2013 opens up a new world to developers.
/Heiko
Hi Heiko,
I use this technique in OIS101 – customer order line open and it doesn’t appear to loose the formatting of numerical values – they are still right justified. Do you have an example program where this happens?
Conditional formatting may well disappear – in the snapshot from Visual Studio you’ll notice that there is a property called Conditions which is a list of CellCondition objects – at the very least there is a disparity between the column counts which is probably not ideal.
And I couldn’t agree more on the rest of your comments. Understanding WPF is extremely beneficial – tools like WPF Inspector and Snoop are invaluable. And it is my distinct preference to use C# – but when I do this for customers I am conscious that taking the step to C# can be a step too far which means that those customers can’t or won’t tweak the scripts. I tend to work on the basis of if there is anything more than simple events and more than ~200 lines of code, C# is my recommendation.
Cheers,
Scott
Like
Hey Scott,
Can you point me in the right direction on how you debugged the JScript in VS? Is that what you you’ve done above? or is this a C# script?
If it’s C# I’d love an example of how you added a column in C# rather than in JScript? I’ve been able to get C# to do everything i need apart from adding a column.
Thanks
Andy
Hi Andy,
in the instance above I believe that I just had a generic C# ‘script’ which had a breakpoint in it and from there I drilled down in to the detail.
I haven’t added a column in C# but you can use the same method as the JScript, there will just be some small syntax differences.
Cheers,
Scott
Hey Scott,
Have you ever added an editable cell to a listview?
Cheers
Andy
Hi Andy,
no, I haven’t but you should be able to use the same logic as you would to add a new column to a ListView – the difference is that instead of populating the column with a string value you use an EditableCell.
Cheers,
Scott
Hi,
I have a requirement that updates editable cells once the user clicks the button and the row has no values in it. In the debug the new value is being shown. However, in m3 the value is still blank. I tried using listView.Items.Refresh(); but still the value is blank. I am not adding a column but rather updating a value of one.
Hi Doms,
how are you setting the value?
Under the Mango.UI.Services.Lists.EditableCell object there is a “SetText()” method which I believe will resolve your problem.
Hi.. Is it possible for you to give me syntax to add new column with editable cells?
I tried adding by adding ‘new Mango.UI.Services.Lists.EditableCell()’ but unable to do so
You’ll probably need to create it with the EditableCell::CreateTextCell static method.
Visual Studios Object Browse defines it as follows:
public static Mango.UI.Services.Lists.EditableCell CreateTextCell(string text, int maxLength = 0, int minWidth = 0, bool isEnabled = true, bool isUpper = false, bool isRight = false, System.Windows.Controls.ContextMenu menu = null)
Cheers,
Scott
Hi Scott!
When I try to add an EditableCell with EditableCell.CreateTextCell, the cell just displays the full class name “Mango.UI.Services.Lists.EditableCell” instead of actually displaying a text field. Seems like it’s calling the toString method of the object.
Do you have any idea why this happens?
Not too sure why, it does ring a bell though – I’ll have a think on it.
Try taking a look at the .Tag field of a normal M3 EditableCell – that may provide some clues.
Hi! Any news on this matter?
The normal EditableCells does not have a tag, as far as I can see :(.
EditableCells should have a public field called Tag.
Taking a closer look at this essentially you’ll probably need to recreate some of the other arrays in that object manually (eg. the Conditions array). Though with a quick hack I could get the edit box to display, I couldn’t get the text to display.
You’d probably have to reverse engineer the code to figure out how get it working correctly, however I suspect that you’ll come unstuck as some of the IListRow properties are read only.
Cheers,
Scott