Introduction

Introduction

 This is the first topic Next topic

Introduction

 This is the first topic Next topic

*** project of writing eNotes for Cologne - German conference - started October 16th. 2013.

==================================================================

PHH - 16th. October 2013.


Resume

Resume

 Previous topic Next topic

Resume

 Previous topic Next topic

After five years working with XAML and WPF, much of this time with Vulcan.NET, I find myself in a position

to write the following as a Resume to my two sessions at 'Vulcan.Live' 2014.

=====================================================================================

XAML technology is now a major component of all current Microsoft APIs - for Desktop, Tablet, Phone, and Silverlight.

The older 'WinForms' technology is now only available as a legacy component in Win32 desktop apps.

'WinRT' does not support 'WinForms'. To many guys 'WinForms' has been dead for a long time.

I last used 'WinForms' about 5 years ago.

===================================

XAML is the mark-up script for WPF on desktops, as well as WinRT (Tablet), and Windows Phone 8 (Smartphone).

XAML and WPF go together like “a hand in a glove”.

Visual Studio 2012 / 13 has XAML editors for all APIs - D, T & P - desktop, tablet, phone and Silverlight.

==================================================

Vulcan.NET and WPF/XAML have been working well together for many years.

I have developed quite a few apps using this combination of .NET technologies.

It is nice to use once we get used to it, I like it a lot - it is VERY productive.

For any professional developer, a solid foundation of XAML skills is a 'must', if he/she is to keep abreast of software changes.

===============================================================

A "HUGE" bonus to a developer when using XAML/WPF is the power and flexibility of the 'Data Binding' underlying technology.

When used correctly, 'Data Binding' with XAML makes life for us developers VERY easy.

'Data Binding' works similarly across WPF, WinRT, Phone8 and Silverlight.

If you are to use Vulcan.NET then XAML is still your GUI technology of choice - it works 100%.

Vulcan and WPF together, make desktop apps.

===========================================================================

At first sight XAML can appear quite daunting, and yet, once we know how best to use it in our app development, it becomes

quite straightforward - even easy!

And whatever others say, it is also quick too.

Yes, there are quite a few new things we need to learn and know, but they are NOT complicated.

First we need some abilities to allow us to get the fundamentals of XAML correct, so our GUI / XAML script is clear,

clean, and easy to follow.

Once we can create clean, tidy, and organised XAML script, then we can deal with the Data Binding aspects of XAML.

Custom objects, and collections of custom objects, is how we approach 'Data Binding'.

I will use 'custom object' and 'business object' interchangeably - to me they are the same thing.

LINQ technology, currently only available to us in C#, makes 'Data Access' VERY easy.

Vulcan.NET 3.0 can live happily 'side-by-side' with LINQ technology within a C# class library, acting as a 'Data Access Layer'.

We will see how to do this after working through all the more basic aspects of XAML and WPF.

XAML / WPF illustrates just how nicely Vulcan.NET and C# play together as .NET Citizens - well done Grafxsoft !!!

==============================================================================================

PHH - 16th. October 2013.


Microsoft APIs - Win32, WinRT and WP8

Microsoft APIs - Win32, WinRT and WP8

Microsoft APIs - Win32, WinRT and WP8

 Previous topic Next topic

Well guys, the news is good !

We can create and write XAML based GUI solutions on all/most of Microsoft's current platforms.

Although in these eNotes we will focus particularly on WPF and desktop app - using Win32 / Win 64 -

we need to know that essentially the same XAML technology exists for the Surface Tablet (WinRT) as well

as Microsoft's smart-phone and Windows Phone 8, as well as Silverlight too.

I have recently done extensive work with XAML on the Desktop, Tablet and Phone. Making use of data binding

and also Prism for MVVM 'pattern' design.

I can thoroughly recommend you embrace and use this technology, life will become easier, nicer, and 'brighter' ;-0)

Let us now look at each of these platforms in turn.

We will start by looking at the XAML script which the Template from VS creates.

In the following four images note in particular the outer 'tag', so we know the UI element being used for the screen.

You ought also to see that there is a main 'Grid' which is also employed by the Template. Each type of technology,

and hence 'Tag' has at least one nested 'Grid'.

Check these out carefully :-

WPF - Desktop (D) :

=========================================================================

Surface Tablet - WinRT ("Metro" style apps) (T) :

======================================================================================================

Windows Phone 8 - 'smart-phone' (P) :

====================================================================================================

Silverlight - version 5 and upwards (SL):

============================================================================

As you can see above, each of these XAML script 'stubs' is just a place to start for the designer / developer guy.

Lets move on ...............

Short Summary - Overview :

There are many similarities in the skills, techniques, and even UI tools used, when we move across the four

software platforms seen/ shown above.

In fact the biggest difference is probably in the 'set' of UI elements seen in the full Toolbox of each.

Surprisingly, the more complex stuff relating to Data Binding and use of MVVM design 'patterns' seems remarkably

similar and consistent, and so many acquired skills are applicable across the board - on all these platforms.

Even when we say that the 'Tool Set' is different, or changes, the way in which we use the UI elements is once again

very similar in all cases.

We finally need to realise that although WinForms is still available to us in Win32 / Win64 technology, it is legacy

stuff, and is completely missing in WinRT and Phone8.

So the wise guys will invest and new learning, and experimental / exploring time, with XAML based technologies.

Good Luck to any and all of you who care to move into XAML and data binding.

See you in the next sub-section .............................

PHH - 1st. November 2013.


C# - XAML solution Templates in Visual Studio

C# - XAML solution Templates in Visual Studio

C# - XAML solution Templates in Visual Studio

 Previous topic Next topic

====================================================================================================================

====================================================================================================================

====================================================================================================================

===================================================================================================================

PHH - 16th. October 2013.


Vulcan.NET - XAML solution Templates in Visual Studio

Vulcan.NET - XAML solution Templates in Visual Studio

Vulcan.NET - XAML solution Templates in Visual Studio

 Previous topic Next topic

====================================================================================================================

PHH - 16th. October 2013.


XAML similarities - WPF, WinRT, Silverlight and Phone8

XAML similarities - WPF, WinRT, Silverlight and Phone8

XAML similarities - WPF, WinRT, Silverlight and Phone8

 Previous topic Next topic

In an earlier subsection we looked at the various XAML script 'stubs' which are generated as

defaults, by the Templates chosen.

We saw that in all cases the screen 'Tagged' UI main element had a least on set of 'Grid' tags nested

within it.

So the main Grid contains the rest of the UI elements required for suitable display purposes.

However, there are far more things in common than this, between each of the four technologies.

Although the basic Toolkit items (UI elements) vary quite a lot across the D,T, P & SL platforms, the much

more fundamental 'things' actually stay the same, it would seem.

By the above I mean that the way Data Binding is handled, and the way XAML objects are bound to data items,

as well as how the bound object classes are defined / declared, is all pretty much constant, or consistent.

So once we master how to create suitable data binding classes in one technology, then these skills carry over

to all the others.

This is also true for knowing how to bind and display collections, in what are called 'Items Controls'.

Using XAML panels and containers to construct DataTemplates is yet another skills which fully transfers.

So 'all-in-all' there is an enormous amount of common ground between all of the XAML based technologies.

If I were asked, I would say that using the XAML design surface and the script editor is basically the same in VS

for any of these technologies - yes a few tools are quite different, but that is quite manageable I feel.

Let us make some observations and see some interesting images.

Items Template - 'DataTemplate' :

Let me take a working section of XAML script and ask you to tell me what type of app it has come from.

Check this out carefully before you answer :-

=================================================================================================

Well, the code for this 'DataTemplate' could be used in a WPF and/or a Phone 8 application.

We could use this to nicely structure our list output, or display.

The only thing which sets it apart from a Tablet app script, is the name of the event used in line 22.

There is no 'MouseLeftButtonDown' event for WinRT. this possibly suggests that WP* and WPF are older

in their origins !?

So basically, the script is usable in all technologies.

While we are on the topic, check out the following image which shows the events available on a TextBlock

in the "Metro" style Toolbox of WinRT :-

===================================

Notice that there is no mention at all of 'Mouse' and buttons. This set of events is 'Touch Centric' and as such

use the sub-phrase (or word) 'Pointer', and also see sneaking in at the end the word 'Tapped'.

We will do a better level of comparative study of the Events across D, P, SL & T later in these notes, and see

how the wording, naming, or event name terminology, gives away the age of the technologies themselves.

The above approach is a very interesting way of looking at these things ;-)

Let us move on a pace or two ...........

Styles & Resources :

The following image shows some Style script which could be in any technology - D, SL, P or T :-

=============================================================================================

The above is true simply because there is a Button class of tool in all of the four technologies.

However, the script in the image below is limited to D & SL - we will see why later :-

============================================================================================

Yes, although the detail of the script for a Style definition looks very familiar, in fact T & P do not

have ComboBox UI controls in their respective Tool-kits.

But the above script could be changed very slightly, and apply to the 'LongListSelector' UI element

of the Phone8 technology.

And in fact, the above script could also be changed just slightly and apply to a Tablet app. - so the

'ComboBox' could be replace by 'ListView'.

Check the following code from a 'Metro' style WinRT app :-

===========================================================================================================

Data Binding :

=============================================================================================================

PHH - 1st. October 2013.


other learning materials

other learning materials

other learning materials

 Previous topic Next topic

http://channel9.msdn.com/Events/Build/2012/2-002

=======================================================================================================

=========================================================

By Rob Eisenberg and Christopher Bennage - ISBN-13 : 978-0-672-32985-2

PHH - 16th. October 2013.


How to learn - Using the walk-throughs

How to learn - Using the walk-throughs

How to learn - Using the walk-throughs

Previous topic Next topic

What is a 'Walk-Through' ? :

When I use the term 'walk-through' I mean that the material I provide will allow you to start a new and

fresh 'solution' in VS2012 and follow each step required to make a working solution and project, by entering

the details and code/script that I show in my eNotes.

So what I provide in these notes is each and every step that I take/make in creating a new application.

If I get it right, and end up with a working project/solution, then you should end up with a work app as well ;-)

The best way to learn application design and development, is to sit with (next to) someone who is a master,

or someone who is experienced in making good apps.

In the UK we call this 'sitting with Nellie' - Nellie being the experienced woman office worker !

The next best thing to 'sitting with Nellie' is to "walk-through with Phil" - hopefully ;-0))

PHH - 1st. November 2013.


XAML - getting the 'Basics' right

XAML - getting the 'Basics' right

XAML - getting the 'Basics' right

 Previous topic Next topic

For guys coming from VO and similar backgrounds, it may well be tempting to rush off to the Toolbox

and start sliding onto the graphical surface a whole bunch of different controls.

A bit like this shown below (but don't you do it ! ) :-

========================================================================

Which was all done by mouse drag from the toolbox, and results in some 'delightful' script

as seen in the following image :-

=====================================================================================================================================

And I have seen much worse than that seen above :((

This sort of script is what puts off loads of guys coming to XAML and WPF - there is no need for it, and no

excuse for us developers creating such a 'mess' !

let us take pride in the quality of our scripting ;-0)

What have we done wrong ? :

Well, we have not planned and structured our window in any way.

All the controls are only nested in the main Grid of the window itself.

We do not have containers, sub-containers, or sub-grids.

The window is said to be 'flat'. I used to create 'flat' forms in VO days, but then there were no

real alternatives.

We need some 'nesting' - "things within things" and we need to make our scrip clean, and clear to

read and understand.

It is said that our UI elements are place 'free hand' on the window / form surface. And if we are not careful

we can move controls out of place without intending to do so.

We can definitely do better than this - even though it may work, and may do as we require for our app.

Improving Things a Little :

======================================================================================

Although the above looks better, there is far more nesting that we can do.

We can place some UI elements within the 'GroupBoxes' for a starter. Lets see how this works out.

Going further - even more -structure and 'nesting' :

Study the improved script layout and nesting in the following DO pane image.

In particular study the Grids within the GroupBoxes :-

==================================================

It may be easier to see some aspects of the improved 'structure' by studying the

XAML script which goes to make the above DO pane details.

Check this out below :-

=======================================================================================================

We have probably done enough for one sub-section of these eNotes, but before we move on to another one

let us see some nice nesting below :- [ Buttons within a Grid, within a GroupBox .. ]

================================================================================================================

And also let us notice that if we place the Buttons directly within the 'GroupBox' then we get an error.

=====================================================================================================

This leads up nicely on to the next sub-section, since the error message means that we have tried to place

more than one 'thing' within the GroupBox.

It will accept one button, but not two or three.

Notice that the 'Grid' tags have been commented out.

We need to study 'Containers' as found in the UI elements.

See you in the next sub-section ....................

PHH - 23rd. October 2013.


UI elements - what can they 'contain' ?

UI elements - what can they 'contain' ?

 Previous topic Next topic

UI elements - what can they 'contain' ?

 Previous topic Next topic

Okay then guys, within the UI elements found in our WPF Toolbox, which ones can take more

than one 'thing' as content.

We have already seen how (in the last subsection) a 'Grid' can be used to contain a few Button controls.

Let us see how the same XAML script may be changed to use another 'container' element.

Check this out carefully :-

======================================================================================================================

So it seems that some UI elements can contain one 'thing', and some many 'things'.

Elements that are restricted to taking 'one' object (or 'thing'), are called 'ContentControls'.

Here is what the SDK docs has to say :-

============================================================================================================

In the last subsection we found out that a GroupBox can ONLY contain a single 'thing' or object. So it can't have

children - in the general.

However, there are differences in some UI elements which can hold (or contain) more than one object. These tend

to be termed 'panels' even when we are talking of a Grid !

So panels have a 'Children' property - see below :-

===============================================================================================================

So basically a panel is a UI element which can have a collections of varying other UI elements.

GUI controls like ListBox, ComboBox, and DataGrids, basically hold many objects (usually similar) but

held within a 'collection' of objects. These are called 'ItemsControls', as they contain a collection of items.

However, as will will see when we do more on Data Binding, the items can be UI elements, like UserControls for example.

The UI elements which can contain many and varied other UI elements, are often referred to as 'container' or 'panel' elements.

These containers are VERY helpful in making us get our Form / Window layout correct, or 'nice' even.

We need to look at :-

- Grid

- StackPanel

- Canvas

- WrapPanel

- DockPanel

- TabControl

- ContentControl ?

It has to be said to guys coming new to WPF and XAML, that the first two of these can be used to do a HUGE amount

of screen design and layout.

I use these most of the time, the others less so.

The Universal container is the 'Grid', and you will see it used within many of the other controls as part of the default layout.

So the Window itself has by default a Grid. This is because the Window element itself can only take one object.

Here is some more SDK information on Children and Panels :-

================================================================================================================

============================================================================================================

So we can't put data items into a Panel - these expect UI elements.

However, in an ItemsControl, like a ListBox, we can add many items to a collection which are actually complex

items with UI and data elements combined - this is part of the beauty of Data Binding ;-0)

It is easy to do, and gets great looking results - just wait to find out how to do it.

PHH - 24th. October 2013.


Window

Window

Window

 Previous topic Next topic

===================================================================================================

=====================================================================================================

===================================================================================================

================================================================================

==============================================================================================================

==================================================================================================

===========================================================================================

==================================================================================================================================================

===================================================================================================

==============================================================================================

PHH - 31st. October 2013.


Grid

Grid

Grid

 Previous topic Next topic

Before we get into details of use within the VS 2012 Designer surface, let us see what the Microsoft

SDK docs has to tell us :-

================================================================================================================

The inheritance 'tree' is interesting as we shall see below :-

======================================================================

Yes, so we see that the Grid inherits from 'Panel'.

This means that it can have a host (lot) of children of type UI element - see below :-

===============================

And since the Grid is such a fundamental UI element we need to read some basic information to help us.

Check this out :-

................

................

============================================================================================================

Let us now move on to see Grids across the XAML world of WPF, WinRT, Phone 8, and Silverlight.

=========================================================================

A widely used and applied 'container' UI element.

The Grid is often used within other elements - by default, as with the Grid nested within the Window

element and the 'UserControl' element.

Check these out :-

WPF :

==============================================================================================

WPF :

==========================================================================================

Silverlight :

=================================================================================================

Surface RT / Surface 2 - Tablet (WinRT / 'Metro' ) :

==================================================================================================

Windows Phone 8 :

=====================================================================================================

In all of the above five images we see that the default script contains at least one set of 'Grid' tags.

In the last image shown above, don't get confused by the use of the 'Margin' attribute, we will explain

this in good time - it comes from being nested within a higher level Grid.

Lets move on a pace ................

Using the Grid - 'Freehand' and Row/Column based :

Even when we have guys using Grid elements within their Designer surface, there are 'better and worse'

ways to use them.

I have to confess to being one who did not use them wisely at the start of my WPF learning experience.

I made the mistake of using a Grid in a MUCH too 'Freehand' way - please learn from my mistakes, and

try to provide some structure to your form with use of Rows and Columns.

Let us examine what I mean by the term 'Freehand' .............

Freehand Use :

Below is an image of an example I made recently of a 'messy' and unstructured form :-

========================================================================

Each UI element has been dragged from the Toolbox straight onto the main Grid.

This means that any reference to placement is done with respect to the top left corner of the Grid itself.

The resultant script seen in the editor shows no detailed structure - check this out below :-

====================================================================================================================================

So in the above script image we see no signs of 'nesting' for the UI elements within the 'main' Grid.

The following image shows the Margin attribute values which define each placement relative to this top left corner.

{ PLEASE ... don't you script and design like this ';-0) }

====================================================================================

Okay then folks lets move on .............

Designing things 'Better' - more structure :

We will now look at a working application for creating invoices, this is used every month end, and has been

for a few years or more.

Although the following WPF form started out life with little underlying structure, it now has been improved a

great deal, even though it is far from being perfect.

In the following image of the Invoices application you will see four main areas of the form :-

=================================================================================================

The section / area in focus above, is in fact a 'GroupBox' with nested UI elements.

Let us now focus on a simpler and smaller 'GroupBox' and then examine some script details.

Here is the 'Create new Invoice' GroupBox :-

=================================================

As you can see above it is not very complex, and contains just five sub-elements within it.

Check out the following script :-

====================================================================================================================

Now then guys, we look to have some structure - BUT - if we examine the script closer you will see (as shown below) that

in fact the five elements are placed freehand within the grid of the GroupBox.

In the following image see that all five elements have Margin attributes with values specified :-

============================================================================

The above Margin values are relative to the top left hand corner of the grid within the GroupBox.

Some benefits of sub-areas on a form - 'Locking' :

The following image shows how in VS 2012 we can now use the DO pane to Lock nested elements.

By clicking the mouse at the right hand end of the Grid item line shown, we can lock all the elements within

the Grid itself.

Check this out :-

===============================================================================================================

We could not do this from VS 2010, and it is an excellent addition to the XAML design surface in my opinion.

However, we need to use it carefully - by locking the Grid as opposed to the GroupBox, the GroupBox may still be

picked up and moved in its entirety - see below :-

====================================================================

'Ctrl + Z' comes to the rescue of course, and if we now change the lock settings by choosing

the GroupBox, then the whole section is locked to the form - see the DO pane details below :-

=======================================================

Unfortunately, I can't illustrate this locking as there is nothing to show. Only a video would demonstrate

the useful behaviour.

So remember, nesting improves locking if nothing else, and with locking we can protect our layouts from

accidental damage !!

Time to move on a pace ...............

Row & Column Use :

One of the whole points of a grid is to form it from lines down and lines across.

I our case the Grid element has Rows and Columns to achieve this.

Once we form some rows and columns we can then use these to place, or attach, our UI elements

within the main Grid shape itself.

I will cover more detail about specifying height and width of rows and columns in the child section to

this sub-section. But for now lets see how we may start to use Rs & Cs.

Let us use for our testing a blank Tab surface - see the nice coloured Tab below :-

==========================================================

Okay then guys lets try to add a few columns in the simplest of ways.

Check out the details shown below - we have created four columns using script directly

typed into the XAML text editor :-

===========================================================================

We will see more later (in the child section) about the ways of specifying numeric values etc..

At this point I have to confess that I usually do all my column and row specification in script.

However, there is an interactive graphical way of adding and removing column definitions.

If we move the mouse pointer into the top section of our Grid we see the following :-

===================================================================

The orange coloured extra column line shows until we release the mouse button.

Once the mouse button is released we see changes to the script and graphical images.

Here is what I just did :-

==================================================================================

First of all we can see in the above image that all our width values have been automatically

changed, and the orange line has become blue like all the others.

In case this is NOT at all what you intended, just press 'Ctrl+Z' once and we see the original

values and script :-

=============================================================================

Moving on lets see how we make a few rows - in a similar manner to the columns shown above.

Check this out :-

===================================================================

Beautiful, we now have a very nice 4 by 5 grid to play around with ;-0)

Let us now see how we may place another UI element in a specific place on our grid, and also

how to use more than one grid square for placement - this is called 'spanning'.

Below is an example in which a Button is 'spanned' across both two rows as well as two columns.

Check this out and study script lines 35 through 38 in particular :-

=====================================================================================

=========================================================================================

=====================================================================================

==================================================================================================

=============================================================================

=========================================================

Time to move on.

See you in the next sub-section ....................

PHH - 24th. October 2013.


Detailed specification of Rs & Cs - width, height

Detailed specification of Rs & Cs - width, height

Detailed specification of Rs & Cs - width, height

 Previous topic Next topic

PHH - 25th. October 2013.


Using the R's and C's to attach elements

Using the R's and C's to attach elements

Using the R's and C's to attach elements

 Previous topic Next topic

Okay folks, we have seen so far how to attach a Button element to the centre of a Grid, and make it span

as well.

However we need to see something more serious as tow how we may position a number of elements to

make up a practical screen for users.

PHH - 25th. October 2013.


Grids within Grids

Grids within Grids

Grids within Grids

 Previous topic Next topic

Grids within Grids :

PHH - 25th. October 2013.


Canvas

Canvas

Canvas

 Previous topic Next topic

A simple observation will help us understand how and where the 'Canvas' UI element fits in to

the overall scheme of things.

If we look in the Toolbox for a WPF project / Window we do not see the 'Canvas' element in the list.

Check this out from VS 2012 :-

================================

The 'containers' seen in the common list are Grid and 'StackPanel'.

=========================================================================================================

PHH - 24th. October 2013.


Canvas in a 'ControlTemplate'

Canvas in a 'ControlTemplate'

Canvas in a 'ControlTemplate'

 Previous topic Next topic

Let us see one of the useful things I have done with a 'Canvas' in many years of using XAML.

We will follow and example from WPF in 24 Hours - see Introduction and learning materials.

E & B (the authors) create a Button which is a little different - using Canvas in Resources.

Lets take this one step at a time.

Open up VS 2012 and start a new WPF project / solution.

To the standard Window & Grid layout, add an 'AliceBlue' background and the following script :-

===========================================================================================================

Yes, this looks nice, and without too much trouble we could add this to a Button.

But what if we wished multiple buttons to look like this ?

How could we achieve some simplification ?

Well, lets make a Static Resource of this, so we can re-use the script multiple times.

Check this out below :-

===========================================================================================================

Since we have moved the whole canvas definition into the Resources section, the designer shows us 'nothing'.

Lets move on a make ourselves a Button within the main Grid :-

==================================================================

Yes, I know, not a lot you are thinking ;-) Well, we really need even less, before we get more!

Try this for simplicity :-

=================================================================

Okay ! - I know, we can hardly see the Button - we will soon put that to rights.

Let us now provide our Button with a 'ControlTemplate' which uses the 'Static Resource' we have

previous mad (above).

Study the details in the following image :-

=========================================================================================

The above looks nice - thanks to E & B - but their written explanations of why the effects are not seen directly

in the design editor have been eclipsed !

Yes, the VS 2012 XAML editor surface shows the results of applying the Resource - technology moves on !!

And so if we now build and run the application we see the following :-

==========================================

Lets move on a pace, and learn a few more skills, tips and tricks.

What can go Wrong ? - multiple Buttons ! :

Well, we can get carried away with our apparent success, and forget that our 'Canvas' script in

the Resources section is actually going to be an object at run time !

The designer allows us to do the following without complaints - check this :-

=========================================================================================

Yes, in the above image we have three Buttons in the text editor of the XAML design surface.

Two are collapsed for display purposes.

We can even move the 'ControlTemplate' to the Resources section as shown in the next image,

check this out carefully :-

======================================================================================

Notice in the above script how we associate the Template attribute with the static resource.

All seems OK, and we see the design surface showing as we might have hoped - BUT - at

run time we hit errors - as the debug attempt shows below - check the details :-

==========================================================================================================================================

Yes, the small details tell us that we can't use one object more than once as a logical 'Child'.

We may be getting ourselves mixed up between applying styles, as opposed to using objects.

In the following image I am making an experiment to see that it is the Canvas that is causing the

problems. By removing the script from line 19 we get a running app, but not many interesting,

or fun, details :((

=================================================================================================================================

We will learn more as we go along, just remember that Resources can have objects as well as Styles

and Templates defined.

So we can use the Template three times over, but NOT the object. Templates and Styles from the Resources

section are applied in the Mark-Up process, so they can be applied many times - whereas objects can be used

only once.

Lets move on .................... and get some more success ...........

Placing 'Content' inside of the Template :

Below we can see that although we have specified "Smile!" as content, we do not get it displayed in

the designer or at run time - check this out :-

======================================================================================

However, if we add the active lines at position 21 & 22 we do see some content displayed.

Once we have the basics working as shown below, we can then go ahead and further improve things.

First of all lets see the basic results :-

================================================================================

With just one attribute being introduced in line 21, we see above that a 'black' smile is centred

horizontally.

However, when we make a few other small changes and additions, we see something like this :-

======================================================================================

And to prove it works at runtime here is what I get on my development PC :-

============================

Okay then folks - fun is up for now, time to move to another sub-section.

See you there .....................

PHH - 26th. November 2013.


Margin attribute - how to use

Margin attribute - how to use

Margin attribute - how to use

 Previous topic Next topic

The 'Margin' attribute is easy enough to understand if we focus on it and try it out with different

situations - however, it can also be very confusing if we rush into using it without knowing exactly

what it is and what it controls.

I know, I have been there !!

Let us start out by saying that Margin is relative.

The numeric values associated with 'Margin' are all relative to a point of reference.

Since 'Margin' is available as an attribute on all UI elements, then we need to realise that the reference

point is the top left origin of the UI element object which is hosting the 'nesting'.

Lets get a deeper feel for this by looking at our crazy 'flat' screen design - all UI elements within

the main Grid of the Window - check this below :-

=========================================================================================

Now then, in the above image I have rearranged the XAML script so that the Margin attribute and its

associated values are displayed at the start of each line.

That way we can see that we have a whole list (or bunch) of elements with varying X1, Y1 .... values.

the other two vales are zero as we are only dealing with the top left hand corners. These values were

done as defaults as I dragged items from the Toolbox.

So then, what happens if we remove by editing, the Margin text from the Button on line 7 ?

See the results shown below - study carefully :-

================================================================

Notice that the Button in question has moved on the graphical design surface to very top left !

If I were to remove all Margin text in a similar way then all the existing elements would pile up

on top of each other in the top left hand corner - one on top of the other.

This is simply because all elements are in the same container, and the Margin values refer to

the container which holds the UI element owning the Margin attribute.

Lets move on ...............

Two Grid containers within a 'main' Grid :

Let us look at an example I have just now made in my VS designer.

Below is two new Grids, each coloured differently, and each with a Button towards the top LH corner.

In fact I simply copied and pasted the Button script from the above 'Flat' messy screen.

Note that the X1 & Y1 are still 39 and 19 - check the following details :-

==============================================================================================================

So what the above image shows is that any element nested directly under the second level of Grid,

has its reference point at the top left of that grid.

If we now remove both of the Margin attributes (and their values) we get the following results :-

=========================================================================================

Okay then, I now here you say "what are the Margin attributes on lines 7 and 13 ?"

And the answer is easy - these are for the placement of the each of the second level Grid elements

within the 'main' Grid itself.

Can you predict what we will see if I temporarily remove them ?

Okay then folks - check this out :-

=======================================================================================

PHH - 24th. October 2013.


Benefits of 'containers' - grouping and locking

Benefits of 'containers' - grouping and locking

Benefits of 'containers' - grouping and locking

 Previous topic Next topic

PHH - 24th. October 2013.


StackPanel

StackPanel

StackPanel

 Previous topic Next topic

In some ways I think of the 'StackPanel' element as the Cinderella of the elements.

When I came to XAML and WPF it was probably one of the first (if not THE first) element to which I was

introduced, and for some reason I was NOT impressed - at all :((

I now realise that this was because it was not introduced to me in the right way - if we see something doing

its job when only it can do the job, and doing it well, then we all have a different sort of respect for that 'thing'.

So now I would say to guys - 'StackPanel' is very good when it is required, and it is particularity helpful when

we need to make data templates for displaying list items.

Don't do what put me off, use a 'StackPanel' to hold two or three buttons - that is NOT its strength !!! - although

it will do it OK.

Instead lets take a look at a good working application - the WorldTime4 app from 'DevShare's ago.

Study these items from a ComboBox drop list :-

==========================================================================

In the above image we have three collection items, displayed using a 'DataTemplate'.

Lets ignore the last one which displays some 'trigger' behaviour and focus on the main aspects

of the DataTemplate.

In the following image let us look in detail at how three 'StackPanel' (SP) objects can be used to make a very

interesting and acceptable item 'data template' to improve our list item display - check this out carefully :-

===============================================================================================================================================

In the above XAML script section we have two SPs within an outer SP.

Lets see what we get if we comment both of the inner SPs - check this out :-

==============================================================================================================================================================================

Yes, as we may have suspected, we get nothing but a collapsed border of colour 'Charteuse', and

width '300'.

Now let us add some content back in by un-commenting the first of the inner SPs - check this :-

==================================================================================================================================================================================

Okay then, this makes sense, what we can see in the above image.

The chartreuse border is no longer collapsed, and it contains four TextBlock objects placed one above

the other - vertically.

Line 31 specifies that the attribute for the SP is a value of 'Vertical'.

If we examine the lines for the 'TextBlock's we see these to be as shown below :-

==================================================================================================================================

So in effect one SP is bracketing together four TextBlock UI elements.

You can also see that each Text attribute of the TextBlocks is bound to a property on a bound collection.

Obviously, setting font related attributes is what changes the text display.

So the following details match the script above :-

==================================

Lets see what happens when we comment the script in such a way so that the other inner SP is commented - check this :-

=================================================================================================================================================================================

In the above image we have now NOT got a first, or left hand side, SP with text details.

This means that the Sp which was on the RHS, is now shifted over to the left.

You can also now clearly see the empty TextBlock object which is used to 'pad' the image so that

it is not hard up against the text.

That are other and various ways to 'pad', this is just an easy way to do it.

So guys, I can tell you that when it comes to data templating, StackPanels are worth their weight in gold ;-0)

Now then let move on a stride or two ..................

Let us look at this another way around :

If we slide from the Toolbox (drag and drop) a StackPanel element onto the Design graphical surface, we see

that we get something similar to when we do the same for a Canvas element.

Check below to see that we get no Grid tags :-

========================================================================================================

The reason we get no Grid tags is because both the Canvas and StackPanel objects can take more than one child.

The SP takes 'children', or multiple contents.

A Grid is only really needed when the nesting object is a 'Content' object which can hold only one 'thing'.

So we say that a Grid, Canvas, and a StackPanel are 'containers' - they can have many children objects

nested within them.

Short Summary :

The StackPanel is a container UI element, and can be set to store (or stack) items vertically or horizontally.

SPs can be placed within SPs - vertical ones may be inside horizontal ones and vice versa.

When stacked items are removed from an existing SP the remaining contents shuffles up to close the gap.

Let us prove the last statement by adding the value for the 'HorizontalAlignment' attribute - Left/Right.

===============================================================================================

And now the Left - see below :-

==============================================================================================================

Note how the padding (spacer) and the photo image move right to left etc..

Now we need to see just what the Microsoft SDK has to say - check this out :-

=============================================================================================

Note in the above image the lack of a 'ContentsControl - so we are not limited to one child item.

=============================================================================================================================================

Okay then, we have done enough to get you going, and so that you fully understand what

a StackPanel is, and how we my use it.

Just remember that any object can be placed into a collection for list binding, so the items

can be composite ones made up from UI elements like StackPanel, TextBlocks and others.

Check out in another sub-section how we may bind to more than one property and yet have the

resultant text displayed in only one TextBlock element.

Time to move on, see you in the next sub-section.................

PHH - 24th. October 2013.


TextBlock

TextBlock

TextBlock

 Previous topic Next topic

=====================================================================================

=====================================================================================================================================

The example we are going to look at is actually one for Windows Phone 8, and the XAML script

and other related UI element stuff is similar to that for WPF and the Tablet.

Here is the phone 'Emulator' output - check the display details :-

=========================================================

The 'Emulator' is based on the phone 8 o/s running in a VM (virtual machine) in Windows 8.1

Here below is the section of script which we need to study - note that we have only a single TextBlock

UI element being used :-

=======================================================================================================

======================================================================================

Sample Script and Interesting Exercises :

Let us roll our sleeves up and get our hands dirty ;-)

That way we may learn more by doing things than be just reading and thinking about it !

Let us start with a new and clean WPF form / window :-

========================================================================

The only UI element on the window is a 'TextBlock' (TBK) and it is scripted as shown below :-

==========================================================================================================

*** Note *** see above how to include escaped characters in your XAML script - so "&amp;" is an '&'.

See appendices for others.

So the new solution in the SE pane looks like this below :-

==================================================================================================================================

======================================================================================================

==============================================================================================

=============================================================================================

===============================================================================================

=========================================================================================================

===========================================================================================================================================

==================================================

=================================================================================================

================================================================================

========================================

==============================================================================

=======================================================================================================================

PHH - 30th. & 31st. October 2013.


TabControl

TabControl

TabControl

 Previous topic Next topic

================================================================================================================

====================================================================================================

=====================================================================

=====================================================================================================

PHH - 24th. October 2013.


Border

Border

Border

 Previous topic Next topic

The 'Border' UI element is a Content Control, so it only accepts one 'child' object.

Here is what the SDK docs has to say :-

=========================================================================================================

The inheritance 'Tree' confirms this see below :-

================================================================

As also does this graphic from the SDK - check this out :-

===============================

As long as we place just one object directly nested in the Border tags things will work out.

Check the following image of a rather more complex sort of Button object :-

===========================================================================================================

Yes, the above image shows the Border containing one object, and that is a Button object.

Now then the Button is also a ContextControl and so must also contain just one object, so this is a Grid object.

Once the Button has its Grid it can then nest many further objects - above we have just two TextBlock elements.

Lets see what happens when we try to 'break the rules' and place more than one object directly within the Border

tags - remember, its a Content Control :-

==========================================================================================================

Yep! the message is telling us that we can have ONLY one child (object).

Now then guys, remember that although the Border UI element is just a ContentControl, and therefore can only

accept one object, the trick to first nest a 'container' object still applies - quite nicely in fact - see below :-

===================================================================================================

And if we replace the 'StackPanel' container with a container of type 'Grid' we do as follows :-

=================================================================================================

So shown above is a Grid (container) nested in the Border element, and then three rows set within the Grid.

Each row has a TextBlock element assigned to it using the 'Grid.Row' attribute.

However, we need to explore what changing the HorizontalAligment can do for us, if at the same time we

remove the local (restricting) setting of the 'Width' attribute value.

Check this out below :-

=================================================================================================

However, we have one further change to make and that is removing the 'Height' value attribute specifications.

Look at the following image to see what we get at runtime :-

==========================================================================================================================================================

Okay the folks, enough of playing around with the Border element.

It can be used to surround and encompass most other UI elements.

We now need to move on - see you in the next sub-section ......................

PHH - 24th. & 26th. October 2013.


Frame

Frame

Frame

 Previous topic Next topic

================================================================

============================================================================================================

PHH - 24th. October 2013.


GroupBox

GroupBox

GroupBox

 Previous topic Next topic

The 'GroupBox' UI element is a ContentsControl class and so any GroupBox object can only nest or contain

one further object.

Check out what the SDK has to say - see below :-

=========================================================================================================

Note above the 'ContentControl' in the inheritance tree.

Here is some further information on this, from the SDK docs :-

=========================================================================================================

And just for fun we will copy and paste the XAML script text from the SDK docs into an empty WPF window.

Here is what initially comes in, after some small amount of my 'adaptation' :-

==================================================================================================

This script shows the following details in the graphical design surface :-

=====================================================

And in the DO pane we can see the object 'nesting' :-

===========================================================

Okay then folks, lets get a bit more artistic, and add a few other changes

to create the following output at runtime :-

========================================================

I will leave it to you to study the XAML script below and find out the changes I made - nothing too clever !!!

Check this out thoroughly :-

======================================================================================================================

Finally, notice that although we are doing quite a lot, our script is still clean and tidy, and can

easily be read and followed.

XAML does not always have to look a mess ;-0)

PHH - 24th. October 2013.


ListBox

ListBox

ListBox

 Previous topic Next topic

Okay then folks, we have seen how 'ContentControl' UI elements can only have one nested object,

now we are going to see which UI elements are termed / called an 'ItemsControl'.

When an element is said to be an ItemsControl it is meant that the UI object itself can take a single

'collection' object. The collection object contains zero, one or many similar items.

To get us on our way with collection related UI controls, let us start with a standard 'ListBox'.

Here is what the SDK documentation has to say :-

===============================================================================================

Okay then, so we can select one or more items from the collection, using the ListBox control.

Notice in the above image that the inheritance tree shows an item (or node?) called 'ItemsControl'.

The ListBox usually is associated with a collection of objects which are or a similar type, or class.

Before we look at populating a ListBox, lets read some more information from the SDK docs :-

=========================================================================================================

Since the modern coding world, and .NET framework approach, is all about Data Binding, then this is the

approach we will take / follow.

Let us look at some simple data items in a suitable collection, and bound to a ListBox - check this :-

==========================

And when we take a look at the XAML script responsible for this we see the following :-

======================================================================================

Please note that we are doing this the simplest way and that when using MVVM we do it slightly

differently - we would not need the 'name' of the UI element.

Below is how we do a simple data binding from our .NET code :-

===================================================================================

And so we now need to see just what class type we have as the collection, and what class and

type the collection objects are.

Look to the following image to work out both of the classes we are using :-

==========================================================================================

Yes, you should have seen that we have a strongly typed List of custom objects. Each custom

object is of type 'RegExDetails'.

The small class called 'RegExDetails' is actually in a class library written in C# - see below :-

=======================================================================

So the simple class has just four properties three strings and a null-able logic/Boolean.

Before we move on to see that we can also use another type of collection, we need to first check

out the template for the data - that which makes our ListBox contents seem readable, and understandable.

Here is the simple data template which was placed in the Resources section of our XAML script :-

===========================================================================

Lets move on a pace ...............

Another collection type - "ObservableCollection" :

In the following image we have bound a more complex collection - one of standard type called

'ObservableCollection' - this is a 'super' form of typed list.

Check this out :-

=========================

And now we need to see that we in fact used the original List<T> collection object, to instantiate

the more complex type of ObservableCollection<T>.

In both cases above the 'T' means, or stands for, "RegExDetail".

Now checkout how I have changed the coding to make this happen :-

=======================================================================================

*** Remember *** that this class is required if we wish to track changes in the collection itself,

that is collection items being added and removed.

Let move on ..............

More information on the 'Data Template' :

Let us now turn our attention to the data template, and what is does for our GUI display.

First of all lets see what we get when we have no data template at all - check this out :-

==================================================

Yes, the above 'mess' is often seen when we are developing new GUIs ;-0)

When I get the above output I count the list items to see if they check out OK, and then

realise that I need to do something with the 'DataTemplate' script etc., etc..

Note below that we have removed the attribute and value for 'ItemTemplate' :-

======================================================================================

Now then, if we replace the script for 'ItemTemplate', and then change the template script so

that we use a different property on the items for 'RegExDetail' we get the following :-

Note the gaps because not all items had a description specified.

In the following image check the new Path value on line 10 :-

===============================================================================

Obviously, for this to show as id does then we have had to replace the attribute script for

'ItemTemplate' - see below :-

===================================================================================

And now let us improve our data template by making it more complex.

We can do more (better?) that have just one string data property output to the screen.

Take a look at this below :-

All we need do is bind two properties and nest them accordingly - here is just one possibility :-

===============================================================================================

Pretty good, but enough for the moment. We can study more on the topic of DataTemplates in

the relevant section

Okay then folks, time to move on to a new sub-section - 'ComboBox's and item selection.

Hope to see you there ........................

PHH - 24th. October 2013.


ComboBox

ComboBox

ComboBox

 Previous topic Next topic

===================================================================================

==================================================================================================

==========================================================================================

================================================================================================================

========================================================

PHH - 26th. October 2013.


DataGrid

DataGrid

DataGrid

 Previous topic Next topic

PHH - 26th. October 2013.


ListView

ListView

ListView

 Previous topic Next topic

*** CARE ***

The 'ListView' (LV) control in WPF is very different to the 'ListView' for 'Metro' / Modern.

The LV element in WPF is more 'old fashioned' - and was probably created years before

that for 'Metro' / WinRT was even thought about ;-)

===============================================================

One way to look at this class is to see it as n enhanced 'ListBox'

The details shown below, from the SDK documentation, confirm this opinion - see

the second to last entry in the inheritance tree :-

[ .. also note that it inherits from the 'ItemsControl' class .. ]

====================================================================

Now the SDK explains that we can have two different 'modes' with the 'ListView' control.

=======================================================================================================

If I was to be cruel I would say that the 'ListView' is for those guys who can't design and create

'DataTemplates'. But I wouldn't say that, would I ? ;-0)

View Mode - One - 'Grid' :

Here is a very 'basic' output when we first try to get some results showing on a new UI control :-

For the above image I used the collection of 'RegExDetail' objects that we used earlier in the ListBox sub-section.

Obviously, we need to improve our display, but first let us see what we had to do to get the basic output as it is.

Here is the XAML script before we attempt to improve it :-

==================================================================

And to complete the data binding in the code (behind) program file we need the following code :-

=================================================================

So what do we need to do in order to improve the runtime look of our data ?

Lets first of all check out a few improvements to the screen / form display :-

This is quite easily scripted in out XAML text.

Check out lines 107 through 112 in particular - see below :-

==================================================================================================================

Now then, see what changes we have in the following image - study carefully :-

Yes, we can change the ordering of the columns, as well as having a tooltip when any of the column

headers are hovered over.

Check line 106 below to see the script which does this :-

===============================================================================================================

And for completeness - if we specify below an 'ItemTemplate' (attribute value) then it only seems to

apply to the 'List' mode, and not the Grid mode.

Adding line 103 does not change the appearance of the output of the Grid mode :-

==========================================================================================================================================================

Let us now move on a pace, and checkout the 'List' view mode ....................

View Mode - Two - 'List' :

below is what we see when we change our XAML script to be using the 'ListView' view mode :-

==================================================================================

Notice that now the script is using the 'ItemTemplate' we specify :-

===================================================================================

In the above image the script for the whole <ListView.View> has been commented.

Now lets move on to the standard (expected) behaviour of sorting by clicking column headers.

Grid View mode - Interactive row sorting :

One of the older style 'things' about graphical tables or grids was to be able to click in the

column header and have sorting applied in a toggle fashion - one way then the other.

We can do this with the 'ListView' element, as can be seen below - check this out :-

=================================================================================

The above image was taken after the first column (TextString) was clicked once.

Now then, shown below is the same screen object after a second (or further) click :-

==================================================================================

Because of the strange bunch of characters in RegEx pattern strings, we may be better to look

at another (simpler) column.

First we need to see what script and code has been placed behind our screen graphical output.

In order to get the sample code working that I copied and adapted from the SDK examples, I have

had to make the header text identical to the property name. here is what I am using :-

================================================================================================

In order to keep track of the immediate history of the header clicking, we also need a couple

of new class variables - or private fields :-

======================================================================================================

We also need a 'sort' method/member to handle the sorting when we trigger it with a mouse click :-

==============================================================================================================

Please note that this stuff may be a little complex / complicated to any guys new to WPF and XAML - but don't

worry as we can live without this is we have to - as I said, it is the old way of doing things, and there are other ways

to do this, and ways I prefer.

So to complete our header click sorting procedure, we need a new member (method) to handle the click event and

to logically apply the correct change requests etc. - study the following carefully :-

========================================================================================================================

Well, the above code doe work quite well as far as the rows sorting and results presentation is concerned.

But we do seem to have an issue with the arrow (up/down) being displayed in the header text :((

Still, this is a little off the main point, or purpose of these eNotes, so we may have to just make a note

to solve the problem later, and move on.

Check out the output after toggle clicking in the 'lTested' column :-

WE now need to look at the end on the list, as there are many blank entries (actually nulls I believe).

So it is the following .NET code which does not seem to do as it should.

I do not know if this could be an issue with the Themes and Styles applied - I doubt it somehow.

With these line below both commented and uncommented, we get the same runtime behaviour.

=============================================================================================================================

======================================================================================================

We may return to this later, but first we have lots more to do.

Lets now move on to the next sub-section, see you there ..................

PHH - 26th. October 2013.


Slider

Slider

Slider

 Previous topic Next topic

===================================================

Good Guy :

http://stackoverflow.com/questions/1321423/does-wpf-databinding-marshall-changes-to-the-ui-thread?rq=1

===============================================================================================================

Lesser Posts ? :

http://stackoverflow.com/questions/8994714/updating-bound-properties-from-a-background-thread

http://stackoverflow.com/questions/3834363/wpf-mvvm-updating-ui-bound-properties-from-backgroundworker

==============================================================================================================

This Article :

http://www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/

=================================================================================================

Is the following 'correct' or indeed sensible ? :

==========================================================================================================

public class AsyncObservableCollection<T> : ObservableCollection<T>

{

private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;

public AsyncObservableCollection()

{

}

public AsyncObservableCollection(IEnumerable<T> list)

: base(list)

{

}

protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)

{

if (SynchronizationContext.Current == _synchronizationContext)

{

// Execute the CollectionChanged event on the current thread

RaiseCollectionChanged(e);

}

else

{

// Post the CollectionChanged event on the creator thread

_synchronizationContext.Post(RaiseCollectionChanged, e);

}

}

private void RaiseCollectionChanged(object param)

{

// We are in the creator thread, call the base implementation directly

base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);

}

protected override void OnPropertyChanged(PropertyChangedEventArgs e)

{

if (SynchronizationContext.Current == _synchronizationContext)

{

// Execute the PropertyChanged event on the current thread

RaisePropertyChanged(e);

}

else

{

// Post the PropertyChanged event on the creator thread

_synchronizationContext.Post(RaisePropertyChanged, e);

}

}

private void RaisePropertyChanged(object param)

{

// We are in the creator thread, call the base implementation directly

base.OnPropertyChanged((PropertyChangedEventArgs)param);

}

}

PHH - 21st. November 2013.


ContentControl

ContentControl

ContentControl

 Previous topic Next topic

When trying to learn about, and understand WPF and XAML, I often look to the Toolbox to see which

tools are present - these are UI elements - and so work back from there, going to SDK docs etc..

If we look into the list of "All WPF Controls" we see the inclusion of a 'ContentControl'. Check below :-

=====================================================

If we drag this to the graphical surface in the XAML Designer, we see the following when we release the mouse button :-

======================================================================================

And the script which is auto-generated in the XAML text editor is as seen below :-

====================================================================================================

For most of us guys (who are not going to become 'gurus' ) we need to know that a 'ContentControl' is where

we are to place any 'UserControls' that we design and create.

In simple (and layman's) terms, it is like having a form within a form, or window within a window.

Let us ease ourselves gradually into this, by reading some of the SDK documentation :-

=========================================================================================================

And here are a few more standard tools (controls) which inherit from 'ContentControl' :-

================================================================

Picking a single one we see the tree for a 'Button' :-

================================================================

Now then, looking deeper into the 'full' Toolbox we see that although we use the term 'UserControl' (UC),

there is not in fact an item called 'UC' in the Toolbox.

Check this out below :-

======================================================

In fact a 'UC' is made from a template - just as a Window/Form is. At the moment, just after release of Vulcan 3,

we do not seem to have a Vulcan template for a 'UserControl' to be used with WPF - BUT - there seems to be

around this ;-0)

You need to go to the next sub-section to find out more on the 'UserControl' in Vulcan as well as C#.

PHH - 26th. October 2013.


UserControl

UserControl

UserControl

 Previous topic Next topic

We must not be scared of the 'UserControl' (UC).

It took me a long time to come to using it, and now I understand a few basic things I realise that

maybe I should have used it earlier than I did.

Think of a UC as a small Form or Window, which then can be used and displayed on a main Form or

Window, in much the same way as a single (or standard) control is.

Generally a UC will be a complex control - complex meaning made up from many, a number of other controls.

Before we move on to do our own exploration we need to see what the SDK docs have to say - checkout below :-

===========================================================================================================

I think it may be coming to make sense that if we have a UC object then we need another control on our main form

within which we can display it.

So a UC is a complex control, and needs a 'suitable' containing control on the main form, which is used to

'hold' it.

The container control used to 'hold' the UC is called a 'ContentControl' and this tool (UI element) is within the

full Toolbox. Check the image below :-

=====================================================

We can have more than one 'CC' on a form/window, and so we can display more than one 'UC'

It is possible to have our UserControls in the Toolbox and then drag them directly onto our graphical designer

surface - BUT - by using a ContentControl we have more flexibility with Data Binding from our code behind.

Let us see a few images from an existing real live app from the Tablet world of WinRT / 'Metro' style coding.

Below we see an image of six similar UCs - these are within 'containers' of type ContextControl.

The image is for an initial display, when only the initial defaults have been applied to each UC object :-

However, when the code behind has provided some values for properties and attributes, we

see a whole different display - note that the drop lists indicate that the Time Zones have been

changed, or set.

In the following image all Time Zones are different :-

===========================================================================================================

What we can't see in the above image, is that the clocks are ticking in real time, and that every five seconds

the display is refreshed and updated.

So our UC has built in functionality, it is not just a bunch of UI elements, it has supporting .NET code in 'members'.

We can improve the functionality of our UC in this case, by adding an image of the guy living in that Time Zone, as

well as providing a check box input for whether the 12 or 24 hour clock should be used for display purposes.

Study the following carefully :-

======================================================

Yes, you are right !!

The above image shows a ListBox of items of type 'MyUserControl' or whatever it is named.

The UC objects can be instantiated and have properties changed and set, before they are added to the

List collection object.

They can also be changed using the two input UI elements seen above - that for Time ZOne and that for

12/24 hours.

Now then folks, moving on a pace, we can see in the next images the UC in a pop-up of a Tablet app, as

well as directly on the bottom right of a 'Page' of the 'Modern'/"Metro" style app.

Okay we know, Terrj Barman does not live in these places below ;-0) Scandinavia is his stomping ground!

==========================================================================================================================================

Lets move on and see how to add UCs to our Toolbox.

See you in the next sub-section .............

PHH - 26th. & 29th. October 2013.


Adding a UserControl to the Toolbox

Adding a UserControl to the Toolbox

Adding a UserControl to the Toolbox

 Previous topic Next topic

Well guys, the good news is that we CAN add our own UserControl definitions to the Toolbox.

Take a look at what we see below :-

===========================================

Sorry ! they are not very imaginative or colourful names, but never the less, they are our own UCs.

Also we need to know that it appears as if we could add the UCs to any Toolbox 'folder' we choose.

Let us start with an empty 'General' folder, and add our first 'UserControl' to this - check out below :-

===========================================

Right click in the highlighted header area of the chosen Toolbox folder and

bring up the context menu - as seen below :-

=========================================================================

Select the 'Choose Items ...' item.

We get a 'Choose Toolbox Items' screen - that shown below is how it will be after we make a 'Browse'

for the correct assembly.

For no just notice that we have the 'WPF Components' tab chosen and in focus.

We will see how to make the checkbox entry for 'UserControl1' in namespace 'WpfApplication1' appear later.

For now just checkout the overall form of the screen :-

==========================================================================================================

In the above screen - once browsing and dll selection has taken place, we see an extra row which needs to be

checked (ticked) for it to appear in the Toolbox.

We are after 'UserContril1'.

Now then folks, when we choose to 'Browse' we see the following dialog screen :-

=====================================================================================================================

In this screen navigate to the correct folder to find the 'dll' which has been made for the Control Library.

This dll should contain the UC called 'UserControl1' in my example - you name may be different.

When we save and close etc., we now see out Toolbox looking like this below :-

===========================================

If you happen to have two or three UCs in the same 'dll' then you could check them all and add them

all at the same time.

Now we need to move on, and see how we can add more than one 'UserControl' to out class library.

See you in the next sub-section ....................

PHH - 29th. October 2013.


Using the added UC from the Toolbox

Using the added UC from the Toolbox

Using the added UC from the Toolbox

 Previous topic Next topic

PHH - 29th. October 2013.


Adding a second or subsequent UC to the library

Adding a second or subsequent UC to the library

Adding a second or subsequent UC to the library

 Previous topic Next topic

Before we added any library folder for our UserControls, our SE pane

looked like the following :-

========================================================

In order to add the library folder we needed simply to right click on the solution

node/item and from the context menu choose to add a new project :-

The following image shows the template options - we needed the one highlighted :-

====================================================================================================================

After choosing this one, our selection caused the following project to be added to

our SE pane - check carefully :-

=========================================================

This is all very fine - BUT - we need to be able to add more UCs when we

so wish.

We need to be able to create something like the next images shows :-

================================================================

The problem at the moment is that in VN3 we seem to be short of an available Template.

I will show you what I mean, and then suggest a work around for the moment. I have reported

this issue to Brian and his Team, to see if they can do something to help.

At the moment, if we right click in the existing UC library we get the following menu options :-

======================================================================================================

Selecting to add a User Control brings up the next image detail :-

==============================================================================================================

And as you can well see we do not have a template for a new User Control - just a WPF form.

Now we need to consider the simple workaround ............

One Manual way to make Subsequent UCs (UserControls) :

For the moment this is a small work-around which seems to work OK. I think Grafxsoft will be able to fix things

soon enough.

At the point in the process (shown above) where we wish to click to add a WPF UC and not a WPF Form, simply

choose the Form option, making sure you 'name' the '.xaml' file appropriately - what you want it to be eventually !!

Below is what I have chosen as a name - 'UserControlManual' - check it out :-

============================================================================================================================

After pressing the 'Add' button we see the SE pane change to the following :-

==============================================

This looks good enough - BUT - the contents of both the '.xaml' and '.prg' files need manually editing.

Lets first look at what the XAML file has within it :-

===========================================================================================

Okay then, we have the wrong Tags, and a wrong attribute.

Window tags need to be replaced with 'UserControl', and the 'Title' attribute needs to become 'Name'.

Here is what I have after manually editing the script :-

=========================================================================================

We will try and work with this later.

First we need to look at the other file, the '.PRG' file - check out below :-

================================================================

All we need change is line 18 where we need our new class to inherit from class 'UserControl'

and not 'Window' as seen above - as well as making sure the namespace is the same as other

UCs in the Control Library - in my case (at the moment) it seems to be WpfApplication1 - see below :-

======================================================================

This namespace goes along with what I have in my directives, at the head of my PRG file, from

where I wish to access the UCs - yours may well be different, just make them 'match', be the same.

====================================================================================

*** CARE *** when you have completed this process you may need to delete the entry in the

References section for the library, then rebuild the whole solution, and then add afresh the library

reference.

Maybe another Rebuild, but then at my end I did manage to add the new UC to the Toolbox.

Here is the choose items screen :-

=============================================================================================

And here is the image of a 'good result' :-

==================================

Okay then guys, we seem to have covered the basic 'stuff' for UserControls.

If anything has been 'thinly' or 'poorly' done it is the member/method support to a class of type UC.

If you wish to find out more about the extra built-in functionality of UCs then go to ClickStart eVolumes

and do a search.

The one to look out for is the Time Zone UC made in the METRO eNotes of ClickStart - this uses a

Thread from the Thread pool, and becomes a real time clock too.

Lets now move on, see you in the next sub-section.

PHH - 29th. October 2013.


Button(s)

Button(s)

 Previous topic Next topic

Button(s)

 Previous topic Next topic

=====================================================================================================================================

====================================

=============================================================================================

=============================================================================================

PHH - 31st. October 2013.


Button (push)

Button (push)

 Previous topic Next topic

Button (push)

 Previous topic Next topic

================================================================================

===================================================================================================================

PHH - 31st. October 2013.


ToggleButton

ToggleButton

ToggleButton

 Previous topic Next topic

PHH - 31st. October 2013.


RepeatButton

RepeatButton

RepeatButton

 Previous topic Next topic

PHH - 31st. October 2013.


RadioButton

RadioButton

RadioButton

 Previous topic Next topic

PHH - 31st. October 2013.


CheckBox

CheckBox

CheckBox

 Previous topic Next topic

=================================================================

PHH - 31st. October 2013.


RichTextBox

RichTextBox

RichTextBox

 Previous topic Next topic

PLEASE guys do NOT get confused or misled by the title of this UI element class.

The RTB (RichTextBox) of 'WinForms' is quite a different 'beast'.

We will see just how different in a short while.

The new RTB of XAML and WPF is a modern class of GUI control.

Here is what the SDK docs have to say about it :-

========================================================================================

Yes, one line and the IMPORTANT part of the line is the 'FlowDocument' bit.

'FlowDocument' (FD) objects are those on which the RTB operates - or if we like, has within it.

FDs are in RTBs - only one FD can be in one RTB element.

Note that the inheritance tree does not show 'ContentControl'.

Let us see how the Toolbox displays to the user this UI element - see below :-

======================================

If we drag a RTB item from the Toolbox pane onto our blank Windows graphical designer surface we

get the following XAML script automatically entered into the XAML text editor - check below :-

===============================================================================

Note in the image above that the RTB tags come with nested 'FlowDocument' and sub-nested

'Paragraph' tags as well.

This is basically telling us what a default RTB is like as well as a default FD as well.

So at this level do NOT think you can just use an old text file of '.rtf' format - things are not quite

that simple I am afraid ;-0)

===============================================================================

When we use separate Paragraph objects we don't need to add extra line breaks.

See bellow for an example - three 'chunks' but only two paragraphs :-

=================================================================================

PHH - 31st. October 2013.


Saving and Loading - other formats

Saving and Loading - other formats

Saving and Loading - other formats

 Previous topic Next topic

The fact that this web link exists, and that we can read the CodePlex article, speaks

for itself - yes, not as easy as we may at first think !!

Below I have sourced and displayed ways to save and load '.rtf' content - BUT - remember, when the

stuff is in the RTB it is in the form of a 'FlowDocument', nothing more, nothing less.

If you need to know more then check out carefully the next two links and some of their details :-

http://wpftoolkit.codeplex.com/wikipage?title=RichTextBox&referringTitle=Home

========================================================================================================================

And now something which looks really useful :-

http://stackoverflow.com/questions/829053/how-to-convert-flowdocument-to-rtf/829088#829088

================================================================================================================

I hope these prove useful to you.

Lets now move on.

See you in the next sub-section ............

PHH - 31st. October 2013.


FlowDocument

FlowDocument

FlowDocument

 Previous topic Next topic

'FlowDocuments' are what the WPF 'RichTextBox' holds, operates on, or even contains.

Forget the workings of the WinForms variety / flavour.

Here is what we get by default when we drag a RTB item from the Toolbox onto the graphical designer :-

==============================================================================================

PHH - 31st. October 2013.


'InLine' elements and the 'InLine' collection

'InLine' elements and the 'InLine' collection

'InLine' elements and the 'InLine' collection

 Previous topic Next topic

============================================================================================================

=========================================================================================================

=================================================================================================================

PHH - 31st. October 2013.


Making text errors in the Editor

Making text errors in the Editor

Making text errors in the Editor

 Previous topic Next topic

=========================================================================================================================

===================================================================================================================

PHH - 26th. October 2013.


the 'Nested' structure of a 'Window', 'Page' and 'UC'

the 'Nested' structure of a 'Window', 'Page' and 'UC'

the 'Nested' structure of a 'Window', 'Page' and 'UC'

 Previous topic Next topic

Main screen objects with XAML technology are very much 'Objects' as we now know them.

So a 'Window' object for WPF will be seen in the DO (document outline) pane as deeply nested.

If we are doing this correctly then we will see plenty of 'nesting'.

Here is a small example - check this out :-

==============================================================================

===============================================================================================================================================================================

================================================================================================================

PHH - 16th. October 2013.


making our first 'nested' XAML window

making our first 'nested' XAML window

making our first 'nested' XAML window

 Previous topic Next topic

If we are going to 'Nest' our UI elements then we need to understand the 'Margin' attribute.

PHH - 23rd. October 2013.


Event 'bubbling' - a consequence of 'Nesting'

Event 'bubbling' - a consequence of 'Nesting'

Event 'bubbling' - a consequence of 'Nesting'

 Previous topic Next topic

'Bubbling', or 'event bubbling', is a consequence of the nested structure of a XAML form / window.

An event can be raised on an object at a low level, but not be handled until it 'bubbles' on up to a

higher level - where it is handled.

This can be very useful to the developer, and save much code writing or generation.

PHH - 16th. October 2013.


the XAML editors within Visual Studio

the XAML editors within Visual Studio

the XAML editors within Visual Studio

 Previous topic Next topic

I am currently using Visual Studio (VS) 2012 as the next version is not on public release until next

month, November 2013.

It can be used to create GUI screens for Desktop (WPF), Tablet (WinRT/Store), Smartphone (WinPhone8),

as well as Silverlight.

In fact only the legacy WinForms does not use a XAML editor in VS2012.

Depending on which template we select in VS2012, we get a Designer surface with text and graphical portions,

both of which can be edited.

If we use C# we can get four editors, as there are Templates for WPF, WInRT and Phone8 - as well as Silverlight.

With Vulcan we get the desktop Template which creates WPF windows / forms.

Lets try and see a few images to back up what I have said.

C# :

First the Desktop WPF Template selection :-

======================================================================================

And this results in an editor design surface like this most parts / areas / sections are quite familiar :-

=================================================================================================================================================================

And now the C# Template for a Metro/Modern/WinRT app :-

========================================================================================

Note the black landscape image.

This gives us a Designer surface almost identical - BUT the tools will be different in the Toolbox :-

=================================================================================================================================================================

And now the Phone 8 C# Template - this is new to most developers :-

===========================================================================================

The Designer surface for Phone 8 is once again VERY similar, but there are fewer tools compared to WPF surfaces :-

=================================================================================================================================================================

And finally the Silverlight template in C# - Microsoft themselves use Silverlight for Cloud apps :-

======================================================================================

And so the Designer surface for Silverlight 5 (and beyond) looks like this :-

=================================================================================================================================================================

Okay - lots of images, which are difficult to read - the knowledge to take away with you is that they are VERY

similar, and work in the same common ways - just the tools are different.

For all Templates and GUI types (WPF, WinRT, WP8 and SL5) there are also supporting panes for Properties,

Document Outline, Object Browser and so on.

The BIG difference is they each have their own set of Tools, and add-on tool kits.

Now the VN3 version ........

Vulcan.NET :

We have only WPF available to us in Vulcan - here is the Template :-

==================================================================================

And this gives the following Designer surface - the tools are the same set as was seen in the C# WPF Toolbox.

Check this out carefully :-

=================================================================================================================================================================

Note that we have lots of tools, more than for Tablet or Phone8 - at the moment.

Short Summary :

Although we have seen five Designer surfaces covering both C# and Vulcan, most of the time they operate it a very

similar manner.

So apart form a varying 'tool set' we can transfer our skills and expertise from one to another - no problems.

This fact makes our lives MUCH easier, and is music to the ears !

We will cover some of these skills in the next section entitled 'Different ways to use an Editor'.

Most of these CHM file eNotes will be aimed at WPF gui creation, and mainly Vulcan3 gui screens and User Controls.

A User Control has to be added like a new Project to the open Solution.

User Control - Vulcan.NET 3.0 :

The following images for a Template in VN3 for a User Control are once again similar to above.

We will see the UC (User Control) in action later in these eNotes. here is the Template :-

=====================================================================================

And now the resulting Designer surface :-

=================================================================================================================================================================

We should see the same bunch of controls in the toolbox as for the WPF form - since it is a WPF User Control.

Time to move on, see you in the next section ......................

PHH - 123rd. October 2013.


the Affect of applying a 'ControlTemplate'

the Affect of applying a 'ControlTemplate'

the Affect of applying a 'ControlTemplate'

 Previous topic Next topic

PHH - 26th. November 2013.


different ways to use an Editor

different ways to use an Editor

different ways to use an Editor

 Previous topic Next topic

The 'MAIN' thing to remember with XAML scripting :

There is one simple idea which we MUST get straight in our heads, and that is that the XAML script

comes first.

By 'coming first' we mean that any items, or GUI elements drawn on the designer surface are done

so because of the XAML script. Script 'text' is converted into graphical display.

If there is an error in the XAML script we have in our text editor, then most often we will see that the

Design surface can't be drawn, and a message is displayed to say this. This may not happen immediately,

but it will if we close the tab and reopen the same '.xaml' file.

Here is a simple example to illustrate the point (it is not difficult to spot the error ... ) :-

=======================================================================================================

In the above image of some XAML script I have simply typed my name into line 10 where the pre-compiler / IntelliSense

system would expect me to be typing an attribute name.

I had to press 'F5' to get the graphical design surface to disappear and the message to show.

However, once I removed the text of my name in the script, the graphical surface refreshed itself immediately.

Here is how it looked as soon as I deleted my name from the attribute 'text area' :-

=============================================================================================================

As long as you know this, and are aware of what some simple typing error can do, then you should not have any

real issues or problems - I don't, and I do a lot of development with WPF and XAML.

So then, the script comes first and then the UI element display in the interactive Designer.

Also, we have no binary code 'stuff ' as in earlier GUI designing tools - just the simple text of the XAML script, that

is the 'master'.

With XAML, the script is 'IT' - that is all there is. From the script (text information) all graphical representation

is created whenever required. Either in the Designer at design and testing time, or at runtime for a finished application.

Moving On :

Now that we are aware of how XAML script is used to create the GUI at runtime, we can move on

to seeing how we can use the VS 2012 editor in different ways.

I have to tell you that I mix up all different ways while I develop an application.

Let us first move on to see the 'script first' approach.

See you in the next section ................

PHH - 23rd. October 2013.


script first

script first

script first

 Previous topic Next topic

'Script First' is the simplest and most direct way of creating XAML based UI elements on the Designer

surface of the XAML editor in Visual Studio.

To show some of the basic points of typing XAML script into the editor, I have created a new and

'blank' WPF form using the appropriate Vulcan 3 template - see below :-

================================================================================================

This new and blank form/window shows up in the SE pane as follows :-

=========================================

As you can see in the above image, the 'BlankTest' form is just one of four.

Obviously 'Window1' was the first one in the Project / Solution - the I made 'Joins.xaml' followed by

'Cologne3.xaml'.

Lets see what our XAML designer surface look like at the moment - checkout below :-

==============================================================================

All of the above (and there is not really a lot) is done by the template we chose / selected.

If we now type in the following text (script) :-

<Slider HorizontalAlignment="Left" Margin="47,81,0,0" VerticalAlignment="Top" Width="133"/>

between the 'Grid' tags we see the whole designer look as follows :-

==============================================================================

By typing the two short lines of text in the editor we see the extra details on the graphical

surface - they appear as if by magic !

However, when we use the mouse (pointer) to pick up the slider control and move it to the top left corner

of our new form, we see that the digits associated with the 'Margin' attribute change in real time as we

move the UI element over the graphical surface.

Here is now what I have on my VS 2012 IDE after such a mouse move - check line 8 :-

=====================================================================================

You may also see that the width attribute on line 8 has changed from 133 to 134 as a result of

the mouse move.

Lets move on, and do some serious copy, paste, and edit to our text in the editor.

Copy, Paste, and Editing :

Okay the folks, let us now copy the 'Slider' text script and paste it into the text editor a few times over.

Below is what I have after copying the slider line five times - I actually used the mouse 'drag and drop'

after highlighting, as my technique for copying.

This is what I have at the moment :-

=================================================================================================================

Above we have simply got six UI elements one on top of another, all with the same position and size.

Here is how the graphical surface looks :-

=========================================================

We can tell what we have by looking into the DO (document outline) pane - see below :-

================================================================

Now let us move on a pace, and manually edit in the text editor, so that the 'Margin' x,y coordinates are

changed to the values shown below :-

===============================================================================================================================

We should now be able to see each of the separate UI elements on the form's surface - check this out :-

=========================================================================

Whoops ! I have just noticed, something has gone wrong with the second element - notice above

that is seems to be shorter than the rest - so if we study the text below we see why :-

=================================================================================================================

I will leave it to you to make any corrections you may need !

If we now tidy up our script to make it easier to read and follow, it looks like the following :-

===========================================================================================

And it may even be helpful for our next simple example if we provide a 'name' for each UI element.

Here is what I have added - checkout the 'Name' attribute :-

========================================================================

Lets go further with our manual editing - make the changes shown below - take your

time and get all the typing correct, this is what you are after :-

======================================================================================

We have added more properties and their values to our Resources section, and then

supplied a 'Value' attribute to each element, along with a numerical value for this attribute.

Here are the results in both the graphical design surface as well as the runtime form :-

=======================================================================================================

One more bit for scripting fun ! Let us make a simple binding in our display.

Using manual typing and editing enter the following script after the 'slider' UI elements - after the tags.

=======================================================================================

Now go and edit the script for the fourth slider to be as seen below :-

===============================================================================================

You may also need to comment a couple of lines we had previously - highlight with the mouse pointer

and then chose the icon shown below - note the short-cut keys are 'Ctrl+K' with 'Ctrl+C' .

=========================================================================

This done correctly looks as shown below :-

=================================================================================

And when we build and run we get something close to the following image :-

============================================

Although you can get the slider to work and show the 'bound' value in the green TextBlock, you

do need to have a much more extensive play around with the Slider control to really get a feel

for how it works.

You need to experiment with Ticks and TickFrequency etc., to improve the display.

Okay guys, all good fun, as well as 'script first', but lets move on ................

What else is 'Scrpt First' good for ? :

Making sure that nesting is correct - and making copy & move changes.

Copy and pasting script from web articles, Microsoft SDK, and eBooks.

PHH - 23rd. October 2013.


Toolbox - 'drag and drop'

Toolbox - 'drag and drop'

Toolbox - 'drag and drop'

 Previous topic Next topic

Enter topic text here.


web articles - 'copy and paste'

web articles - 'copy and paste'

web articles - 'copy and paste'

 Previous topic Next topic

This short section deals with the GREAT benefits of having a 'script first' GUI designer.

The designer is made form a text editor section and a graphical interactive 'element' surface.

the script editor has built-in excellent intellisense functionality and features.

The 'Design' surface can be used to move UI elements around using the mouse, as well as

have UI elements dragged from the Toolbox.

Any working script copied from web and eBook articles / pages, should paste into the script

editor and work right away.

Obviously any pasted script needs to be an integral section - complete in itself - in order to work.

PHH - 16th. October 2013.


Grouping and Locking - UI elements

Grouping and Locking - UI elements

Grouping and Locking - UI elements

 Previous topic Next topic

PHH - 18th. October 2013.


Some differences - with WPF, WinRT & Phone 8

Some differences - with WPF, WinRT & Phone 8

Some differences - with WPF, WinRT & Phone 8

 Previous topic Next topic

The truth is that there are MANY more similarities in the XAML used in all Microsoft UI technologies

than there are differences.

However, we do need to be aware of the differences when we come to use WPF, WinRT, Phone 8 and

also Silverlight.

Although many folks may never use Silverlight they do need to realise that it is included. I believe that

it is Silverlight which is used for Office 365 - yes, Microsoft using their own new technologies ;-0))

Missing tools from the box !? - Label in WPF is missing.

PHH - 16th. October 2013.


the Toolbox

the Toolbox

the Toolbox

 Previous topic Next topic

PHH - 16th. October 2013.


the Main UI element

the Main UI element

the Main UI element

 Previous topic Next topic

WPF / Desktop :

This is a 'Window' class object - see below :-

==================================================================================================

WinRT / Tablet :

This is a 'Page' class object - see below :-

==========================================================================================================================================

(Windows) Phone 8 / Smartphone :

This is a 'PhoneApplicationPage' as seen below and also in the DO (document outline) :-

=========================================================================================================

Here now is the associated 'DO' pane :-

======================================================

================================================================================================

==========================================

Sub-Classed Types :

Sub-classed object types may also be used for any of the above technologies. Obviously these sub-classes need

to be appropriate types.

Here is an example where an MVVM type for 'Prism' is being used :-

=========================================================================================================

If we now look at the assembly :-

===========================================

In the Object Browser we see that VSAP inherits from Page - check this out :-

========================================================

And here are the added members for the VSAP class :-

====================================================================================================================

PHH - 16th. October 2013.


the References section in SE

the References section in SE

the References section in SE

 Previous topic Next topic

===================================================

==============================================================================================================

==============================================

==========================================================

PHH - 16th. October 2013.


the Events for UI controls / elements

the Events for UI controls / elements

the Events for UI controls / elements

 Previous topic Next topic

PHH - 16th. October 2013.


Controls for 'binding' to Collections

Controls for 'binding' to Collections

Controls for 'binding' to Collections

 Previous topic Next topic

A 'collection' is seen by XAML as being a single item which contains many 'items'.

So we have list based controls which have an 'ItemsSource' attribute / property.

Such controls are 'items' based and commonly used ones are :-

ListBox, ComboBox, DataGrid, and ListView.

I tend to use these 'most' in the order as seen above, with ListBox being very frequently used.

Below we see how two ComboBox (or drop list) controls have a binding set on lines 57 & 58.

=========================================================================================

When we bind in this simple manner we need some supporting script lines - be aware, at first they

appear to have 'stuff' missing.

Let us see what they look like in the body of our XAML script - the main mark-up section :-

=====================================================================================

Above, notice that the 'Name's of the controls match those used in the .NET code.

But where are those other attributes we expect ?

Well, don't forget that we commonly clean up our body script by using Styles in a Resource Dictionary.

So if we look at a typical 'Resources' section we see the following :-

===========================================================================

Now we can see those extra property/attribute assignments, and look, the 'ItemsSource' attribute is

now seen to be set for binding from the .NET code.

Moving on a step or two, we see a very typical member from the .NET code which provides us with a

list of typed items - check this out below :-

====================================================================================

Yes, in the above code we see that we are making a list of Enums of type 'StringFunction'.

Lets take a quick look at the SE pane details, so we can see what is going on :-

==================================================

As you can see above, we have a number of Enum specifications within a file in a suitably

named folder.

Here in detail is the one we are focusing on right now - the 'StringFunction' :-

=========================================================

And from the working drop list at runtime we see the following :-

==============================

To get this demo to display for these eNotes I used the code as seen below - see line 26 :-

=============================================================================================================

Okay the folks, time to move on and see some related tips and examples of displaying collections

within suitable UI elements, or controls.

Here is proof of 'Items' control capability in the four controls mentioned above :-

===================================================================================

===========================================================================

===========================================================================================

====================================================================

That is a useful way to compare the four controls, and their binding attributes in 'action'.

Lets move on.

See you in the next sub-section ..............................

PHH - 18th. October 2013.

Addendum :

We can keep things simple if we define our own 'ToString' method.

Here is an example - check this out :-

=======================================================================

If we run the app with no data template, we see that we get the following output :-

==================================

And if we adjust the 'ToString' method as seen below we can get an alternative display :-

================================================================================

Using the 'ToString' method on the class of the item to be held in the collection, bound to the

list control, is one way of displaying combined fields.

Another way is via binding, and other controls used within a 'DataTemplate'.

Finally, we have another output format being used - check this below :-

=================================================================

Time to move on .................

PHH - 31st. December 2013.


DON'T Dos !!

DON'T Dos !!

 Previous topic Next topic

DON'T Dos !!

 Previous topic Next topic

*** Note *** This sub-section contains my personal ideas and recommendations.

======================================================================

In earlier times I gave myself a lot of unnecessary grief by using the wrong sort of 'contents' to fill

a list based UI element.

I would advise you NOT to use simple data types like 'string' and 'int' if at all possible.

Use an Object.

They best thing to do (for a host of good reasons) is to make a simple custom type, and then a

collection of these typed objects. This always works for me.

Try to avoid using XAML script to create short lists 'on the fly' in the XAML editor - see below :-

==========================================================================================

Yes, you see the above script in many examples on the web - BUT - this approach causes problems

and issues later - as we shall see.

However, for now, here is this sample display at runtime - see below :-

=========================

Thinking ahead to developing our skills, placing data in the XAML script is a definite 'no no' when

it comes to using the MVVM pattern.

Here is a better way, although it still uses a simple type - check this out :-

=================================================================================================================

At least in the above image we have moved the data assignment from the script into the code, so this

could be in our Model or ViewModel when it comes to MVVM development.

Lets move on ...........

Getting at the Values :

So now that we have these two ways of simply filling a list box with basic type items, how

do we go about extracting ones that are selected ?

Here is an updated runtime screen image :-

====================================================

So in the above example, how did we find and extract the values 'Billy' and 'Elizabeth' ?

We can start by looking at the following Vulcan .NET code - lines 37 & 42 in particular :-

=========================================================================================================================

The above methods are both event handler methods - for the 'SelectionChanged' event.

We are really wishing to focus on the fact that we need to cast any 'SelectedItem' from an ItemsControl, and

also that for the simply made XAML script sample we need to use 'ListBoxItem' as a type.

This caused me endless issues when I was new to XAML and binding - now I just do it the Custom object way,

and all works fine.

Even though the 'string' approach seems better, it still will cause issues for binding in more complex situations. I

will explain this later, and also a better way to handle things so that we can track through 'property changes'.

For the moment, check out the script which supports the filling of the blue 'TextBlocks' :-

========================================================================================================

Just for your information, there is an alternative way of picking up (or accessing) the selected list item.

In the following image we are using one of the event args - note that for single selection (as opposed to

multiple selection) from the list, the item we require has an index of zero, as it is the first one in the

selected collection.

Study these details carefully :-

=================================================================================================================================================

We still have a few ways in which we can improve what we are doing.

Lets move on to see the "YES - dos" section ...........

See you there.

PHH - 18th. October 2013.

Addendum :

An alternative syntax, and way to fill a ListBox from XAML script - but NOT what we will end up doing regularly

in the near future ;-0)

Check this out below :-

=========================================================================================================

Th make the script in lines 28 - 35 work we first need an extra line in the namespaces at the head of

the XAML mark-up file.

Checkout line 6 which then allows us to make 'string' objects directly within the ListBox.

Since we are then no longer using 'ListBoxItem' objects in the specified collection, we can then simplify the

binding on line 57 in the 'Text' property binding of the 'TextBlock' element displaying the selected detail.

And going a bit mad, what about this the ? Checkout below :-

==========================================================================================

And here is the runtime result :-

==================================================

Yep the correct double is displayed after selection - AND - all we did was change the .NET type from

'string' to 'double'.

PHH - 18th. December 2013.


DON'T Dos !! (2)

DON'T Dos !! (2)

 Previous topic Next topic

DON'T Dos !! (2)

 Previous topic Next topic

Guys, I have added this small section to improve out joint knowledge of XAML and how to interact with .NET code,

or at least .NET objects from the XAML script and mark-up side of things.

In the world towards where we are headed (MVVM and further) the essence is to separate out as many things as

possible, and certainly not to put data into the script lines themselves.

However, what I am about to show you is interesting as it shows us how the namespace declaration works in the

XAML mark-up files.

Take a look at the following image, line 7 in particular :-

================================================================================

By us providing line 7 we create a 'link' between the XAML script, back to the .NET code file where the

namespace " Vulcan3ConsumerOfLINQ" is present.

You can see the .NET end of this in the next image - see below :-

==============================================================================================

Now then, on line 132 in the above image, we see a class definition for 'Person'.

And since we now have a 'link', or reference back from the XAML script to the .NET code, we can actually

create 'Person' objects in our XAML script !

PLEASE bare in mind that is NOT recommended by me as a way to do things - AND - it certainly is not the

MVVM pattern of development ;-0)

We are doing this for knowledge of how all stuff XAML works !!!

Carefully, check out the following image details :-

=============================================================================================================

As you can see in the above image, even at design time the ListBox element shows content which

appears to be correct.

In the lines 30 through 35 we see a bunch of 6 person objects being placed in the collection bound to the

ListBox 'ItemsSource' attribute.

You will also notice above that the 'DataTemplate' is being used - it is associated in line 29. At the moment

we are only displaying 'Person' property details.

While we are at this, we may as well see what the designer and 'IntelliSense' system shows us as being on

offer in a context sensitive drop list menu - notice some user defined properties :-

===================================================================================

So then folks, what do we get and see at runtime ? Check this out below :-

==========================

Okay, much as we expected, but what about more and improved data values, for other properties ?

Well, this is easy to do, take a careful look at the following image detail :-

=========================================================================================================

Yes, once again at design time we can see suitable list box content.

We have improved the 'DataTemplate', and also added some address data values.

And here is the real-time result :-

==============================

Now then, for those tidy minded folks, we can reduce the amount of script text, by removing or

missing out the unused property values - check this out below :-

=======================================================================================================================

The above works fine, however, you do need to realise that this is because we have a suitable 'empty'

constructor and 'Initialise' method - see details below :-

==============================================================================================

Time to move on ...............

Okay then folks, to summarise the above ......

Don't do it at all, or certainly on any regular basis - making .NET objects in the XAML mark-up script.

But you need to know that this approach does work, and for many different 'Custom' objects as well.

You would find issues when it came to objects with properties of collections. More of space and order

perhaps than technical impossibilities.

Have fun - just don't do it !!!

PHH - 19th. December 2013.


YES - Dos !

YES - Dos !

 Previous topic Next topic

YES - Dos !

 Previous topic Next topic

Okay guys, we have seen how NOT to do it, and ways we marked as 'could be improved', so what

are we going to do differently ?

Well, first of all lets see the use of binding to improve the way we display a selected list item.

We will comment out the event and its handler method for both the list 'SelectionChanged' events.

The code now looks like the following :-

===============================================================================================================

So if we no longer rely on an event to load the 'TextBlock's with a value, how do we do it ?

Well, the ListBox is still bound to the collection we supply in our code, but we now focus on the

TextBlock elements to see how we bind them to a property on the ListBoxes.

First, lets check out the script for the ListBoxes and the style for the TextBlock - see below :-

==================================================================================

Okay, above is what we may expect, so what have we done to create a binding from the TextBlock ?

We need to study the following carefully, and make sure we understand what it all means.

Check this out in detail :-

=============================================================================================================

Quite simply, the above script means that the Text attribute (or property) of the TextBlock, is bound to the

property / attribute on the specified element, to the property specified in the 'Path'.

Look at line 33 above and see that this may be a bit of a puzzle to you - this is one of those cases I talked of

earlier where the simple approach of using a 'ListBoxItem' directly in script makes it more difficult for us to find

and handle the property where the value is to be found.

To new guys, it can be a long time, and much frustration before they try " \SelectedItem.Content ".

Line 36 in the above image is far more obvious and intuitive. But there is yet a better way - just be patient.

Finally before seeing the runtime details, note that 'SelectedItem is a property/attribute of the ListBox control. This

means we are binding property to property - no events involved at all.

Before we move on lets see this new data binding way of displaying selected item text, one not using events :-

=====================================================

Yep! it works very well, and also takes some pressure off the event handling system of WPF, so

better performance should result.

Lets move on ...............

The BEST way - using a 'Business' or 'Custom' class :

Okay then, the way I recommend you do your list binding, to list and grid controls, is by using a 'business'

or 'custom' control - suitably set-up in a manner which ALWAYS will work for us - real time changes will be

seen directly on the GUI surface, no matter how the item properties are changed (by code or interactively).

Here is a collapsed view of the 'Person' class - a full expanded text version is in the child folder from here.

Check this out carefully :-

==============================================================================================

The above shows the 'PropertyChanged' event and the handler method - these are crucial to the visual success.

All data properties should then use the event as seen below for the 'Address' property :-

===============================================================

======================================================================================================================

=============================================================================================================================

============================================================================================================

PHH - 20th. October 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

==========================================================================================================
<Window x:Class="Vulcan3ConsumerOfLINQ.Cologne3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Cologne3" Height="400" Width="500" Background="LightGoldenrodYellow"
Name="winCologne" DataContext="{Binding}">

<Grid>
<Grid.Resources>
<DataTemplate x:Key="ourGBU">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Person}" />
</StackPanel>
</DataTemplate>

<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="87" />
<Setter Property="Height" Value="24" />
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="Background" Value="SkyBlue" />
</Style>
</Grid.Resources>

<ListBox HorizontalAlignment="Left" Height="96" Margin="23,21,0,0"
Name="lbxLBI" VerticalAlignment="Top" Width="87" >
<ListBoxItem Content="Tom" />
<ListBoxItem Content="Jack" />
<ListBoxItem Content="Billy" />
<ListBoxItem Content="Sarah" />
</ListBox>

<ListBox HorizontalAlignment="Left" Height="96" Margin="159,21,0,0"
VerticalAlignment="Top" Width="100"
Background="GreenYellow" Foreground="Maroon"
Name="lbxFromCode" ItemsSource="{Binding}" />

<TextBlock Name="tblkLBI" Margin="23,137,0,0"
Text="{Binding ElementName=lbxLBI, Path=\SelectedItem.Content}" />

<TextBlock Name="tblkListT" Margin="159,137,0,0" Width="100"
Text="{Binding ElementName=lbxFromCode, Path=\SelectedItem}" />

<ListBox HorizontalAlignment="Left" Height="96" Margin="302,21,0,0"
VerticalAlignment="Top" Width="159"
Name="lbxCustom" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Person}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<TextBlock Margin="302,137,0,0"
Text="{Binding ElementName=lbxCustom, Path=\SelectedItem.Person}"
Name="tblkCustom" Width="159"/>

<Button Content="Make Code Change" HorizontalAlignment="Left"
Name="pbMakeCodeChange" Margin="302,175,0,0" Height="26"
VerticalAlignment="Top" Width="159" Background="LightGreen"
Click="pbMakeCodeChange_Click"/>

<ListBox HorizontalAlignment="Left" Height="124" Margin="23,235,0,0"
Name="lbxGood" VerticalAlignment="Top" Width="111"
ItemsSource="{Binding Path=GoodOC}"
ItemTemplate="{StaticResource ourGBU}"/>

<ListBox HorizontalAlignment="Left" Height="87" Margin="258,235,0,0"
Name="lbxBad" VerticalAlignment="Top" Width="87"
ItemsSource="{Binding Path=BadList}"
ItemTemplate="{StaticResource ResourceKey=ourGBU}"/>

<ListBox HorizontalAlignment="Left" Height="87" Margin="398,235,0,0"
Name="lbxUgly" VerticalAlignment="Top" Width="87"
ItemsSource="{Binding Path=UglyList}"
ItemTemplate="{StaticResource ourGBU}"/>

<Label Content="{Binding Path=LabGood}" HorizontalAlignment="Left"
Margin="23,209,0,0" VerticalAlignment="Top" Width="87"/>

<Label Content="{Binding LabBad}" HorizontalAlignment="Left"
Margin="258,209,0,0" VerticalAlignment="Top" Width="87"/>

<Label Content="{Binding Path=LabUgly}" HorizontalAlignment="Left"
Margin="398,209,0,0" VerticalAlignment="Top" Width="87"/>

<Button Content="Remove Last" HorizontalAlignment="Left" Margin="148,339,0,0"
Name="pbRemoveLast" VerticalAlignment="Top" Width="101"
Background="LightCoral" Click="pbRemoveLast_Click"/>

</Grid>
</Window>
==========================================================================================================
class Person implements INotifyPropertyChanged
// ----- Fields -----
private _person as System.String
private _address as System.String
private _DoB as DateTime
private _phone as System.String
// ----- Events -----
event PropertyChanged as PropertyChangedEventHandler

//----- Methods -----
constructor()
super()
self:Initialize()
return

constructor(cP as string, cA as string, dtDoB as DateTime, cPH as string)
super()
self:Initialize()
self:_person := cP
self:_address := cA
self:_DoB := dtDoB
self:_phone := cPH
return
//------------------------------------------
protected method Initialize() as void
self:Person := ""
self:Address := ""
self:DoB := DateTime{1900,01,01}
self:Phone := ""
return

protected method OnPropertyChanged(name as string) as void
local propertyChanged as PropertyChangedEventHandler
propertyChanged := self:PropertyChanged
if (propertyChanged != null)
propertyChanged:Invoke(self, PropertyChangedEventArgs{name})
endif
return

//----- Properties -----
property Person as string
get
return self:_person
end get
set
self:_person := value
self:OnPropertyChanged("Person")
end set
end property

property Address as string
get
return self:_address
end get
set
self:_address := value
self:OnPropertyChanged("Address")
end set
end property

property DoB as DateTime
get
return self:_DoB
end get
set
self:_DoB := value
self:OnPropertyChanged("DoB")
end set
end property

property Phone as string
get
return self:_phone
end get
set
self:_phone := value
self:OnPropertyChanged("Phone")
end set
end property

//----- Methods -----
static method GetPersonOC() as ObservableCollection<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Adam Savage","19 Upwards CRescent",DateTime{2000,10,10},"01633 101010"})
aListP:Add(Person{"Jackaline","13 Front Street",DateTime{2001,02,02},"01633 345876"})
aListP:Add(Person{"Adrianne","26 Back Street",DateTime{2003,03,03},"01633 3334455"})
aListP:Add(Person{"Geraldine","39, Side Alley",DateTime{2004,04,04},"01633 667788"})
aListP:Add(Person{"Frederick","2 Down Close",DateTime{2005,05,05},"01633 221133"})
aListP:Add(Person{"Susanah","53 Main Street",DateTime{1997,07,07},"01633 772377"})
local implied oOC := ObservableCollection<Person>{aListP}
return oOC

static method GetPersonList() as List<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Adam Savage","19 Upwards CRescent",DateTime{2000,10,10},"01633 101010"})
aListP:Add(Person{"Jackaline","13 Front Street",DateTime{2001,02,02},"01633 345876"})
aListP:Add(Person{"Adrianne","26 Back Street",DateTime{2003,03,03},"01633 3334455"})
aListP:Add(Person{"Geraldine","39, Side Alley",DateTime{2004,04,04},"01633 667788"})
aListP:Add(Person{"Frederick","2 Down Close",DateTime{2005,05,05},"01633 221133"})
aListP:Add(Person{"Susanah","53 Main Street",DateTime{1997,07,07},"01633 772377"})
return aListP

static method GoodPersonList() as List<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Adam Savage","19 Upwards CRescent",DateTime{2000,10,10},"01633 101010"})
aListP:Add(Person{"Jackaline","13 Front Street",DateTime{2001,02,02},"01633 345876"})
return aListP

static method BadPersonList() as List<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Adrianne","26 Back Street",DateTime{2003,03,03},"01633 3334455"})
aListP:Add(Person{"Geraldine","39, Side Alley",DateTime{2004,04,04},"01633 667788"})
return aListP

static method UglyPersonList() as List<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Frederick","2 Down Close",DateTime{2005,05,05},"01633 221133"})
aListP:Add(Person{"Susanah","53 Main Street",DateTime{1997,07,07},"01633 772377"})
return aListP

end class

==========================================================================================================
BEGIN NAMESPACE Vulcan3ConsumerOfLINQ
partial class Cologne3 inherit Window

public aListCP as List<Person>
public oMyMG3 as MixedGuys3

constructor()
super()
InitializeComponent()
self:Initialize()
return

method Initialize() as void

self:oMyMG3 := MixedGuys3{Person.GetPersonOC() , ;
Person.BadPersonList(), Person.UglyPersonList()}
local implied aList := List<string>{}
aList:Add("Elizabeth")
aList:Add("William")
aList:Add("Richard")
aList:Add("Benjamin")
aList:Add("Franklin")
self:lbxFromCode:DataContext := aList
//-----------------------------------
self:aListCP := Person.GetPersonList()
self:lbxCustom:DataContext := self:aListCP
/* local implied oMG3 := MixedGuys3{Person.GetPersonOC() , ;
Person.BadPersonList(), Person.UglyPersonList()}*/

/*local implied oMG3 := MixedGuys3{Person.GoodPersonList(), ;
Person.BadPersonList(), Person.UglyPersonList()}*/

//oMyCollection

//self:winCologne:DataContext := oMG3
self:winCologne:DataContext := self:oMyMG3
return

private method pbMakeCodeChange_Click( sender as System.Object, ;
e as System.Windows.RoutedEventArgs ) as System.Void
foreach p as Person in self:aListCP
if p:Person == "Jackaline"
p:Person := "Justin Change"
endif
next
return

private method pbRemoveLast_Click( sender as System.Object, ;
e as System.Windows.RoutedEventArgs ) as System.Void
//MessageBox.Show(self:oMyMG3:GoodOC:Count:ToString(),"Count :")

local nLast as int
nLast := self:oMyMG3:GoodOC:Count-1
if nLast >= 0
self:oMyMG3:GoodOC:RemoveAt(nLast)
endif
return
end class

end namespace
==========================================================================================================

==========================================================================================================

PHH - 18th. December 2013.


Displaying Enums (1)

Displaying Enums (1)

 Previous topic Next topic

Displaying Enums (1)

 Previous topic Next topic

Background :

Enums have been around a LONG time, going right back to the beginning of .NET itself.

This inevitably makes them, at least in some ways, old fashioned !

However, if we go about things right we can use Enums in a more modern way, and make and bind

collections of them in place of old fashioned strings.

As developers we OFTEN create our own enums - BUT - we must not forget the .NET is fully and

fundamentally based on enums - this is part of its 'charm'.

Lets start by looking at some built-in enums ..............

Making a Start - accessing "System Enums" :

Let us see what MSDN can do for us, here below is a useful section :-

=====================================================================================================

From the above information image we will choose to use and try out the File related enumerations.

First we will look at some 'FileOption' values / names as shown in the following runtime displays of a

ListBox and ComboBox bound to suitable arrays - check this out :-

==========================================================

In order to produce the above runtime displays we needed to use the following .NET code.

Checkout lines 31 and 32 to see the use of the STATIC methods 'GetNames' and 'GetValues' :-

=========================================================================================================

To be honest with you I can't see what the difference is between these two static members - we will return to

this puzzle in just a moment.

First we need to see the runtime display of four of the 'File' based enumerations - check this out below :-

===================================================================================================

Yes, the lower drop list elements are bound to arrays made from the same Enum type as the list box

above them.

The list boxes have the Values array, and the drop lists the Names array.

Now then, before we move on, lets do a test to see just what we have in the Names array - see below :-

===============================================================================================

Yes, as we thought, they arrays for Names is a string array, and this also seems to be the case for Values,

which is NOT what we might expect.

Lets move on to Enums made by ourselves - as developers ...........

Application based 'Enums' :

Lets do a test - below is an Enum I made for a previous example in my eNotes.

As well as the name I have also provided a value - values are optional - check this out :-

======================================

Now then, we will use three new ListBox elements to display arrays and a collection List all

from our new Enum.

We will make arrays from names and values, and also make a list of the 'Enum' objects themselves.

Study the following VERY carefully :-

===================================================================================

Now then, that may be a surprise, as I expected the Values to shows as 2,4,8,16,32 !?

So lets just get on with things, we may find out more later.

Below is the designer surface to show you what goes along with the .NET code from above. Check this out :-

==============================================================================================================

Okay guys, things are looking good, but time to move on .................

How do we make using 'Enums' feel a bit more modern ?

Which Types of Items ? :

Okay then guys, the 'Enum' static methods of 'GetValues' and 'GetNames' are indeed quite useful - BUT - in

many ways they are old fashioned.

I say this because these provide a 'System.Array' of strings, and there does not seem to be way of getting a

list of objects of type of the 'Enum' being used / provided.

In my data binding development, I much prefer to use collections of the actual type being used, not 'string'

representations of them.

If we bind collections of complex business object items then why not 'Enums' as well. Using strings feel like

going back ten years!

Lets do a test to prove that we get string 'objects' in our arrays - check the details below :-

==================================================================================================

In the above image you see that we are printing out the type of the items within the array generated.

This means that we can make our own way for generating a collection, using a List<T>.

In the following image, line 72 shows the .NET way of parsing each of the array items to create an 'Enum'.

[ .. the third input (Boolean) is to set whether to ignore the case of the text string .. ]

================================================================================================

And YES ! - we do need to cast on line 72, even though we have specified the type elsewhere in the method

inputs.

Let us see what we get at runtime now that we have a bound list of 'Enum' objects :-

==========================

It is also a good idea to checkout just what type the new collection items are - see below for details :-

=================================================================================================================

Yes, we have moved from an array of strings to a collection of 'ViewType' (enum) objects.

So this means that we can use and bind any selected item from the List controls, not as strings but as 'enum' objects.

That way we are treating every collection and binding in the same way.

I like that !

See you in the next subsection ..................

PHH - 14th.& 19th. December 2013.


ListBox (2)

ListBox (2)

 Previous topic Next topic

ListBox (2)

 Previous topic Next topic

The ListBox UI element in XAML / WPF is one of the commonest controls used, as well as it possibly

being the most useful and most flexible.

For more details on the general use of ListBox elements visit the next subsection.

At the moment we will follow up details in the last subsection, where we displayed Enum collection items in

both ListBoxes and ComboBoxes.

=================================================================================

XAML script - to support System Enumeration displays :

============================================================================================================

===============================================================================================

=================================================================================================

PHH - 14th. December 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

=========================================================================================

=========================================================================================

=========================================================================================

=========================================================================================

PHH - 14th. December 2013.


ListBox (general)

ListBox (general)

 Previous topic Next topic

ListBox (general)

 Previous topic Next topic

Hi guys, well the good news is that the ListBox control (or UI element) is extremely flexible as well as

being very easy to use and set-up.

Collections of custom or business items are easy to bind to a ListBox control.

Here is a basic example, shown in the following image :-

================================================================================

Above we see the XAML script for a list box named 'lbxTestWIthComboBox'.

Line 46 set-up the situation where we can easily bind a collection object from the .NET code.

Here is the .NET side of the binding :-

====================================================================================

And we also need to take a quick look at the code below, where line 193 gets a List<T> of type

'Person' and makes an observable collection which is returned by the method.

Check this out :-

=============================================================================================

Okay then folks, we can see from the list's rows (6 in total) that we are doing something right when

we try and display at runtime - however - we could do with a data template to improve matters.

Lets try a simple one first - see below :-

===========================================================================================================

Yes, certainly better than no template at all - BUT - it could do with some improving I feel ;-0)

Let us first see how the data template is used in the body of our XAML script - check this out :-

===========================================================================================

See above that line 56 is where the association is made between attribute/property and Resource object.

Lets move on and add some extra row fields, or effectively columns. Lets add a drop list element, or ComboBox.

Check this out :-

==============================================================================================================

Notice that in the above script we see that the 'ItemsSource' of the ComboBox is bound to an item

property called 'Friends'. The property of the collection item class is called 'Friends' and must be a 'collection'.

Possibly a typed list or an observable collection. The runtime image displays an example of such a filled drop list.

Lets us see how this simple test was achieved. Here is my first simple trial :-

========================================================================================================================

Obviously, in the above image the 'aF2' object is a typed List - of strings.

In this simple test each Person has the same List assigned to the 'Friends' property.

Here is the corresponding 'Constructor' - check this out :-

========================================================================================================================

Okay then guys, let us tidy up the XAML script a little, and also add a couple more elements to the

data template - study this carefully - see below :-

=======================================================================================

See above that we have removed the 'spacer' element, given the template elements a fixed 'width',

and added two extra elements, one a 'ComboBox' and the other a 'CheckBox'.

It is necessary to bind a certain attribute (property) of each element to a property belonging

to the collection item. There are five such bindings seen above.

Note that in script line 17 we have chosen to set the three state property to true. We need to

do the same for out Person property otherwise we can get runtime issues - see below :-

=======================================================================================

The red line of the 'Border' around the CheckBox is indicating a validation error. This tells us that

the bound property of the Person class object is only 'two state' and can't take a 'null'.

The situation can easily be changed by changing a small amount of code in the Person class.

Here is one change along with the working runtime display :-

======================================================================================

And here is the other, where we specify / define the fields for the Person class, check this out :-

===================================================================================

Line 54 is where we have changed to a three state logic variable - from the previous 'two state' one.

To put it simply - as a summary - the UI element and the class field have to match. Either they are

both "two state", or both "three state", but it is not a good idea to mix them.

Moving on to improve our Drop List contents :

Okay then folks, let us see if we can have different collections associated with each of the ComboBox

UI elements - so that each row is different in this respect.

Check out the following example - one that I have coded just now :-

=========================

Notice above that we seem to have much more variety than we had previously.

And the following code is partly the reason why - check this out below :-

====================================================

So if we have six different collections, how do we use them to make our runtime

drop list as different as they are ?

First of all, lets see another image to demonstrate the differences we have coded into our app :-

========================================================================================================

If we choose to construct our Person class objects with a string (name) which is included in

the collection supplied for the 'Friends' property, then we see some text on the ComboBox at app

launch time.

By selecting a name from a drop list we actually select this name and it is then associated with the 'Friend' string

property of the Person class object.

PHH - 28th. December 2013.


ComboBox

ComboBox

ComboBox

 Previous topic Next topic

"Basic Use" - simple items in collection :

Remember - we said that collections of simple data types and ComboBoxItems / ListBoxItems

would possibly make things more difficult for us at some point down the line !

Let us start simple, with a 'simple' custom / business class we define ourselves.

Here is a data binding on line 26 - see below :-

=========================================================================

And at runtime we get the following screen display if we have a 'ToString' method as shown :-

=======================================================================

Defining our own 'ToString' method is a simple way to get some display results, without a need

to resort to a 'DataTemplate'.

Here is a semi collapsed version of our simple class - entitled 'Friend' :-

======================================================================================

The above class is of the 'shape' of all of my 'suitable' classes for binding - check them out

in one of the other sections of these eNotes.

Lets now see the simple XAML script used :-

========================================================================================

Although we use a 'Name' and .NET code for binding, remember that when we move to using the

MVVM 'pattern' we simplify this even further.

Here are the STATIC members which provide for us a collection of 'Friends' :-

=========================================================================================

And when we use the 'OC' (observable collection) - with an alternative 'ToString' method, we

see the following displayed - check this out :-

============================================================================

And here is another alternative :-

==============================================================================

And yet another useful alternative :-

=================================================================

Moving on to some interactivity / item selection .............

Selecting List Items :

Okay then guys, before we look at selecting from the list of items, we need to have a suitable

TextBlock UI element in which to display the item selected.

In the following image study the two controls required, and shown :-

===========================================================================================================

And when we build and run the app we see the following on our windows surface :-

=====================================================================

The selected item 'detail' is still that of the 'ToString' method of the Friend class.

Let us now move on to a more complex item class, and using a 'DataTemplate' for display

purposes.

More Advanced Use - collection items of complex 'Business' class :

Having had a simple string displayed in the drop list, to represent our item, we now move

on to displaying a full and complex area of detail, for each item represented in our list.

Check out the following image :-

===================================================================================================

In the above image, each of the red rectangular shapes is a complex collection item.

The item is made up from text, logic, drop list, and date picker UI elements - all of which are

active and usable at runtime.

Let us see our XAML script definition of the ComboBox - check out below :-

===========================================================================================

Notice the 'Auto' setting on line 68 above - this is quite useful indeed, and I suggest you trial

it and test it out yourself.

The biggest issue in the above script is the item template used on line 71 where an association

is made between a resource object and the item template attribute of the ComboBox.

Here is what this script produces at runtime :-

========================================================================================

And now we need to move on to see just how much interactivity is available to us.

Check out these next few images - first we look into the 'DatePicker' :-

==============================================

And after that bit of 'date' fun we can check the drop list within the data template :-

==============================================

Each drop list has a different list of items, within the selected item itself.

Something about Triggers ! :

==========================================

=========================================================================================================================

Images in ComboBoxes :

We often need to add images or photos into items within a ComboBox control. Check out the Image

sub-section in the next main section from here.

PHH - 29th. December 2013.


DataGrid

DataGrid

DataGrid

 Previous topic Next topic

Many developers 'love' a grid - the equivalent UI element in WPF / XAML is called 'DataGrid'.

I fell in love with the DataGrid control when I was using DataTables in ADO.NET.

Now that I have given up all ADO.NET technology (on the coders level at least) I now find it equally

useful and applicable with item collections.

Below we see such a binding, a collection with the 'ItemsSource' attribute / property of the DataGrid :-

====================================================================================================

The above simple data display is a result of clicking the 'Prod no Sales' button. We see some simple string

data as well as some simple numeric data.

First of all lets see the Click event method handler, and how the binding is made :-

=====================================================================================

Obviously the data association on line 45 uses a STATIC method to supply the information.

The STATIC method is within a C# class library and is seen in detail in the following image :-

[ .. this is a pretty standard / regular way of using LINQ to SQL .. ]

===========================================================================================================

Okay then folks, so we have our data, supplied from a STATIC method in the class library.

So how do we get it displayed in the grid (DataGrid control) ?

Here is the simple association - first the XAML script end of things :-

=============================================================================

And then the .NET code side of things :-

======================================================================================================

Remember that when we use the MVVM development pattern (MVL) we will not use Names of UI elements.

We will also not use click events either, just keep that to the back of your mind as we see how to do

things the basic / standard WPF way.

Going a bit further - what about some more complex data - a larger item class, that of Customer.

Check this out below :-

=============================================================================================

Yes, in the above image we see some more complex data types, Boolean and DateTime as well as

string, integer and doubles.

Let move on .............

How to set-up the 'DataGrid' in a more 'fancy' way :

Okay then folks, we have gotten quite a bit of functionality to display our collection with really very

few lines of XAML script - so far we has the following 'ONLY' :-

==================================================================

However, we can do lots of things to rows, columns, headers, and much more, by using some of

the many attributes the 'DataGrid' control possesses.

Let us now consider a more fancy screen display for the same grid and data - check this out below :-

================================================================================================================

In the above image I have taken the live grid output, at run and display time, and moved a bunch of columns around,

as well sort the rows on the 'FirstName' descending.

If you are clever, you will even see how I have adjusted the width of some columns so that we get a suitable 'gap' or

space between the styled header contents.

Lets move on and see what we have available ............

First the Attributes in use :

There are many, many attributes available to us, but some or more commonly used than others.

Let us now take a detailed and careful look at which ones we have used to produce the above runtime display.

Check out these below :-

========================================================================================

In the above image I have tried to arrange the property / attributes so that they are grouped in

some way that makes sense to us.

There is no technical reason why we need to organise them like this.

Most of the above make simple enough sense to a guy with even a little experience of XAML script.

Many of the above you can experiment with and explore on your own.

However, line 101 needs some extra discussion by us while we are on the subject of 'Headers'.

Notice that in line 101 we are associating a Style resource with the 'ColumnHeaderStyle' (CHS)

attribute - one named 'myColHeadStyle1'.

Lets look in detail at the script in our Resources section for this - checkout below :-

=================================================================================

Most of the stuff in lines 15 through 21 is reasonably straightforward and self explanatory.

However the 'Triggers' section which contains just one 'Trigger', needs a little explanation.

First lets see what the standard output looks like when we move the mouse pointer into the

column heading and then click - note the caret 'pointer' in the following images :-

=========================================

Note that in the above images the rows are sorted by 'FirstName' and A to Z then Z to A.

[ Top to bottom, and bottom to top. ]

So what happens when we apply our Style to the heading ? Check out the next image seen below :-

==========================================

Oh! we have quite a different set of headings, and also a tooltip - BUT - we have also

lost the 'caret' to show us the order of our sorting.

If you study the following screen display image, after it has been sorted by a header click,

you will see that the sorting facility still remains, its just that we have lost the 'pointer' which

is obviously part of the default Style we have overwritten ;-0((

Checkout the following :-

========================

Let us now see if we can make up our own 'Trigger' and add it to the Triggers collection.

We need to select a Property (attribute) to use, other than the one already used called 'IsMouseOver'.

Let us try using the 'IsPressed' property - checkout below :-

===================================================================================================

As you can see above, we get displayed in the header a yellow text (foreground) when we

click (or press) the header area with the mouse pointer / button.

We can further enhance this by making the background black as seen below :-

=====================

So the XAML script to make this happen is as highlighted in the next image :-

=======================================================================

Finally on this one, we can make the whole experience better - that of hovering over a

column header and then clicking it - if we change the Trigger for 'IsMouseOver'.

Take a carefully look at the two following images - one is while the mouse button is

pressed and held :-

==============================================

So what happens is that if we see a yellow on black image at any time, then that particular

column will be sorted and the newly sorted shown when the mouse button is released.

Study thoroughly the changed XAML script shown below :-

===============================================================================

You can now go and experiment for yourselves - chose different properties and make

different 'setter' definitions / value associations.

Time to move on, lets look at Grid row changes ................................

Remove / Delete - Rows :

For many guys having data in a data grid type control means editing and changing the data - as a

commonly used option.

If we are to allow the data to be edited in the grid cells (i.e. control is NOT read only) then we usually

also wish to allow lines (rows) to be added and/or removed.

===============================================================================

*** Note ***

The UI element called 'DataGrid' has properties / attributes which help us manage the editing of data which is

within the grid cells.

In the following image you can see how we can easily set whether the data grid cab be changed at all, and

then if rows can be removed or added - each setting is a Boolean - check below :-

==================================================

Obviously, the term 'User' means the person interacting with the UI screen - rather than a code based change.

===============================================================================

First let us look ate removing (or deleting) rows - check out these next two images - keep an eye on

'CustomerId' = 1 :-

========================================================================================================

With the highlight showing row one is in focus, we press the 'Delete' or 'Del' key on the the keyboard.

The row (or line) immediately disappears - check below :-

====================================================================================

The above display means that the first collection item has been removed from the collection - it has

gone for good !

If we keep pressing the 'Del' key we will empty the collection completely - see below :-

======================================================================================

What we need is a way of seeing how many items are in our collection.

Lets see if we can report on the collection length at grid display time - check out this .NET code :-

=============================================================================================

And when we click the button to populate the DataGrid we see the following on screen :-

=======================================================

Okay then, so we start with five items in the collection.

And here is an extra Button we can add to check the length of the collection at any time.

By 'length' I mean generally how many items are within it - not a 'Length' property.

Here is our button with a click event associated with a handler method :-

====================================================================

Let us now run our application and use the length report button a time or two :-

=================================================================================

Yes, it would seem from the above images that both one and zero report without any error, or crash.

And here is the .NET code which reports back to us :-

==============================================================================================

So we can simply delete rows easily, from our collection, and when the GUI is replaced, or disappears,

we still have the amended collection in memory as our processed data.

When we move over to using the MVVM 'pattern' we will supply the data coloection from the ViewModel code,

or even (most likely) from the Model code which we use to 'project' into the VM constructor - this data then gets

bound as VM properties to the UI elements in the View.

This way we are editing Model data items directly at the GUI surface.

Lets move on a pace or two .............. lets try adding more data .................

Add Extra Rows :

Okay then folks, if we can remove rows of data, how can we add any ?

Well, the answer is easy, the facility exists within the DataGrid control itself.

Remember the ' CanUserAddRows="true" ' high up this page ?

Well, if we set the value to be 'true' then we get some built-in functionality we can use on screen.

Checkout the following image - see some new detail in the row in focus :-

==========================================================================================================

And here is some more, with line 15 having been added and the focus placed back with 'CustomerId' = 13 :-

=========================================================================================================

Yes, we have to be aware that for some cell data type entries we will get error warnings :-

[ .. see if you can spot what is wrong with the date / time .. ]

===============================================================================================

But to show that dates with time may be entered OK, we have the following two image(s) to it :-

===========================================================================================================

And the next one two ..........

==============================================================================================

When we do get one or more validation errors on a line, we see at the extreme LHS that a red 'pling' is displayed.

Checkout the following image :-

=========================================================================================

There is a whole topic to be studied when it comes to data validation, so we must leave things as they are

for the moment in this section, as it is simply about DataGrid controls.

Before we leave, lets see how we can control the headings shown by code means, rather than an

auto-generated 'full set'.

Setting our own Headings :

Well then guys, there are definite benefits to using 'Auto-Generation' of columns in the 'DataGrid' control.

And if we turn off the related property / attribute we may see something like this :-

================================================================================================

In the above image the numbers of coloured rows shows the collection length, but

we do not see a lot more ;-0)

Now then, if we wish to show just a few chosen columns - these are really chosen properties of the

items in the collection - we can do something like the following :-

=========================================================

The headers still have the same Style set on. And we can still sort the rows.

Here is an order of rows determined by 'Credit' limit low to high :-

=======================================================

And to give us an idea of how this is done we need to study the following details - lines 115 - 118 in particular :-

==================================================================================================================

Note that in the above image we have specified the absolute width of the columns. This can prove useful

so that we don't have to adjust the width at the very start of displaying details.

Also we may not allow column re-sizing so we would need to get things right from the word 'go'.

Personally, I prefer to try and do things in 'Auto' mode, so that we leave as much flexibility as possible. We will discuss

this point more a little later on.

For the moment lets remind ourselves of the script we are using to provide the style to the headers.

Check this out below :-

============================================================================

Yes, and the Tiggers still work in our newly defined column structure too :-

=========================================================================================================

In the above image, as well as seeing that our yellow/black triggers work as previously, we can

also see that there is an 'Auto' mode for the 'Width' property / attribute.

And we can also 'ease' the header display by adding extra space(s) to the column header text. The

following image shows the improvement one extra space in the header does to the 'look' - check this out :-

=============================================================

In lines 116 and others, we have an extra space after the colon.

Lets move on a pace, to see what we gain and what we lose by doing this 'customisation' of the DataGrid.

Pros and Cons - benefits for the 'Auto-Generation' approach :

Having used 'DataGrid' controls quite a lot, over many years, I personally like to use then in as generalised

way as I can. With columns being auto-generated etc..

If we have a 'DataGrid' on a form and leave it to display itself (sort itself out) then we can bind any sort of

collection - just like I am doing with the demo example I am using here.

Study how we are binding very different collections from the code sample shown below :-

======================================================================================

Product with no sales, customers with no order, and orders with order items, and there is more as well.

Now then, as well as keeping things general by using AutoGenerated as 'true', we probably need to see

that adding our own header styles will show at window launch time, and not when we bind the chosen

collection - as we did initially.

Note that in the following image we get headers for a specified, or particular, collection before we even

do any data binding.

Check this out :-

============================================================

Okay guys, I realise that when we all get very good and experienced with XAML there may well be ways

around this - BUT - I am trying to provide you with simple ways to get going with Data Binding and MVVM as well.

Short Summary :

If you are to use a 'DataGrid' control for only one type of collection (fixed item properties), then customise the

headers and columns as you see fit - otherwise stick with auto-generation and keep things as simple as possible.

Below is an image of one of the generalised 'bindings' the headers come from the collection item properties.

Note now different the layout of the columns is to the earlier one we studied :-

=====================================================================================

Now then folks, time to move on, lets go and learn something about the ListView control.

See you in the next sub-section ..................

PHH - 20th. & 21st. & 23rd. December 2013.


'DataGrid' Columns of various types

'DataGrid' Columns of various types

'DataGrid' Columns of various types

 Previous topic Next topic

When we choose to not use the 'Auto-Generation' of columns within the DataGrid control, we then

have quite a variety of choices open to us.

=========================================================================

As well as being able to define and name our our columns, and then bind them to suitable properties

of the items in the collection being displayed, we can also choose the 'Type' of column.

If we study the following image we see columns of type 'Text', 'CheckBox', 'ComboBox',

as well as a 'template' variety which can be set up with a template for Dates.

Before we get into any further details study the details carefully :-

==================================================================

In the above image we see the drop list (ComboBox) displaying the small group of string values on offer.

Any selected (or displayed) value under the header of 'Friends' is a chosen 'Friend' value. 'Friend'

being a property of the collection item - in this case a string type.

Here in the next image is the possible column types available to use for use :-

===========================================================

Only the 'Hyperlink' one is not demonstrated in this sample sub-section.

Let us now see the 'Template' variety in use, with a 'DatePicker' control defined - check this :-

============================================================================

We will see more later on how to set up a DatePicker in a DateTime column.

For now, lets concentrate on the drop list form of the column, and how we need a suitable string property

for the case in hand. Notice that each item has its 'Friend' property set to a value of 'dick' - check this :-

==================================================================================================

In fact, after the above code was tested I removed the string 'List' property, so that now we have

no property / attribute with the name 'Friends'.

Here is the remaining string field for '_friend' which is used with the Friend property :-

=========================================

And now the new property we have added to the Person class :-

===========================================================

The binding of the Person item collection is done like this in .NET code - check line 27 :-

=============================================================================

And the other part of the data binding can be seen in the next image on line 26 :-

========================================================================================================

Extra, in the above image we see five DataGrid special 'Columns'. Notice that the Source of the ComboBox column

type is not specified, or bound. However, we have defined the binding of a selected drop list item to the string

property of the collection item - on the 'Friend' string property.

Below, we see that line 35 provides the 'ItemsSource' property value as the defined short 'string' list :-

========================================================================================================

You may also like to know that there is no 'DataContext' property available for binding, on the 'DataGridComboBoxColumn'

class - so we can't do binding in the usual way I would turn to.

And below we see the binding of the ComboBox selected item with the 'Friend' property on 'Person' :-

=====================================================================================================================

Finally, we need to be reminded of the Resources section entries for STATIC resource items needed

for use with the column Template and its associated Date elements :-

===============================================================================================

More on this can bee seen in the 'DatePicker' section of the next section.

Time to move on ...................

See you in the next subsection.

PHH - 24th. & 27th. December 2013.


ListView - two modes 'List' and 'Grid'

ListView - two modes 'List' and 'Grid'

ListView - two modes 'List' and 'Grid'

 Previous topic Next topic

Handling the future - by knowing the past ! :

Well guys, we need to look at this from an Historic point of view.

Yes, "History" in ICT and programming - whow! ;-0)

If we search the MSDN documentation correctly we see that the 'ListView' was first included with framework 3.0

but that the 'DataGrid' was introduced much later, in framework 4.0 - and there was a 3.5 version release in between.

So we have probably a good couple of years between one control and the next - LV to DG !

This would suggest to me that many (most?) of us will now use the DataGrid control in place of the ListView one.

Some of us may never have used the ListView in programming 'anger' - maybe just to complete some learning notes.

For this reason I will not spend much time on the 'ListView' control as we now find it in .NET 4.5

PHH - 23rd. December 2013.


Controls for 'binding' to Properties

Controls for 'binding' to Properties

Controls for 'binding' to Properties

 Previous topic Next topic

As you may be aware by now, some UI elements, or GUI controls, are designed to take lists

where others are designed to 'take' or be 'bound to' single valued properties.

In this section we will look at TextBlock and TextBox which are basically designed to take string

types - but that can be changed - and others designed to take numeric types, dates, and also images.

The 'slider' is good for numeric values, usually integers, and the DatePicker is great for dates using a

DateTime .NET data type.

PHH - 18th. October 2013.


TextBox

TextBox

TextBox

 Previous topic Next topic

PHH - 1st. January 2014.


TextBlock

TextBlock

TextBlock

 Previous topic Next topic

The 'TextBlock' is a simple enough UI element - it is a control to allow the R/O display of text.

The 'TextBlock' element is used in many different places both on the mains UI surface, as well as within data

templates for displaying items from a collection.

The question we need to ask ourselves when we use the 'TextBlock' control is "Where does the data come from?".

You will see as this section unfurls what we mean by 'where does it come from'.

First lets see the easiest XAML script way - check below :-

[ .. data within the script ..]

==========================================================================================

On line 88 shown above, we are hard coding some string data into the property called 'Text' on the TextBlock

class of objects. This is NOT the MVVM way of doing it ;-0)

The above script displays at runtime like the image shown below :-

[ .. but it does not change .. ]

===============================================

Lets try a runtime approach, from .NET code ..............

[ .. data within the code - which can be changed at runtime ..]

================================================================================================================

As you can see above, line 55 sets (or changes) the 'TextBlock' string data. This can be driven

by business logic.

However, we would be better advised to keep the data 'outside' of the properties of the UI element itself. This

we can do by binding another data object to the 'Text' property of the control.

Data Bound - from a third party object :

Let us see another approach, one which moves towards MVVM - check out the following image and its detail :-

===========================================

The string data seen above is in a property of a data object, and an object which is bound to the

Text property of the control - so the data is NEVER within the control itself. So we are starting to

get 'separation'.

Let us now look in detail at the code which handles an Image control mouse down event.

Notice that lines 79, 85 and 91 are changing a property on the main window object - more commonly

we would be using a separate class of data object - like 'Customer', or 'Order'.

Check this out carefully :-

==========================================================================================================================

And so we need to see just how I have coded the new field and property for 'Message'.

In the main Window1 class we have a field called '_message' and a property called 'Message'.

Note also that we have to handle the change in value of the property :-

====================================================================================

Without the 'implements' detail on line 20, the mouse click does NOT change the bound data string.

Lines 23 through 44 are the basic essence of what other suitable classes for binding are like.

Below is where we set the .NET side of the data binding, as well as the value of the bound property :-

===============================================================

In the above image the crucial line is 50, in which we bind the main Window1 object to the TextBlock object.

We would not normally do it like this but it is an improvement to holding data in the property directly on the

UI control itself.

So every time we have a code change of the 'Message' property, we see a change of string information

on the TextBlock - see the three examples below :-

====================================================================================================================================

And finally, we need to check out the XAML script side of the binding - see below :-

==================================================================================================

We will see more of this binding from external data objects when we move towards MVVM and its 'pattern'

of development and code/script writing.

With MVVM (MVL) it is easy and clear to make this sort of binding happen for us.

Time to move on.

See you in the next sub-section .....................

PHH - 1st. January 2014.


Image

Image

Image

 Previous topic Next topic

Although the Image control is a simple enough UI element, it is rather an important one. We need to know

how to use it in some common situations.

Let us start out very simply, by wishing to display a chosen image file.

Below I have made a script in XAML for a TextBlock and an Image control - check this out :-

====================================================================================================

We need to change the 'Text' attribute of the TextBlock from when it was used for the ComboBox trial.

Now we need to select a suitable image file - here is my Properties pane and the Source selection :-

================================================

You may need to check out for yourselves the Stretch and Direction options ;-0)

In the following image we have made the text changed, and have also associated a Source file image with our

Image UI element - check this out :-

=====================================================================================================

And when we build and run the app we see the following on our monitor :-

===============================================

Okay, we need to check that our solution has an Images folder, and a few suitable images too.

Here is what I have at the moment (in my SE pane) :-

======================================

[ .. the Build Action needs to be set to Resource for each image file .. ]

And when we place the Image control in focus we see the following detail

in our Properties pane when we select the 'lightning' symbol, top right :-

===============================================================

By clicking in the vent input box the auto-generated name is created by the IntelliSense system, as

well as a .NET code stub being made. Below I have added a simple line at 45 :-

===============================================================================================

So when we run the app and click the image / photo, we see this :-

======================================================

Let us now improve out even method handling code - here is a start :-

====================================================================================================================

Okay then, above we have changed our display photo to that of Eric.

Let us make a cyclic method 'response' which goes around three images.

==========================================================================================================================

The above does work quite nicely and I have made a short video for the Vulcan.Live slide show.

Here is the third of the cyclic image set :-

=====================================================

Lets move on to something more complex and useful ? .............

Going further, images in List Controls - an Image bound to an item property :

When we bind collections of items to list and grid controls, we often require that an image be shown too.

For example when we have customers or persons, or even lists of product items.

Here is my own example from many years back - it was done for 'DevShare' - check this out :-

====================================================================

As you can see above, we have a list of developer guys, their time of the day for their particular

time zone, and also a 'mug' shot ;-0)

As you can see below, once an item is selected the image for the item selected is shown larger

on another Image control. Check out below :-

===========================================================

You may have noticed that apart from a small and a large image of Mike Pitcher, we also

see some small icon images - those for parts/times of the day. Check below :-

===========================================================================

The point of showing this is to remind ourselves that we can also set a 'Tooltip' for the Image control.

Below is the XAML script for the 'Noon' icon - the sun in the middle :-

============================================================================================

I will leave it up to you to add your own image to a DataGrid row. There are a couple of ways to do this,

but first see what I have done in the ListBox and DataGrid sections.

Think "Templates" !

PHH - 1st. January 2014


Slider

Slider

Slider

 Previous topic Next topic

PHH - 18th. October 2013.


DatePicker

DatePicker

DatePicker

 Previous topic Next topic

This has been around since .NET 4.0 days - it is a very useful and versatile control..

We can't examine it in GREAT detail, as we have not time and space to do so ;-0)

However, we will look at some interesting uses of this UI element. Lets start simply :-

We can start our exploration of the DP (DatePicker) by seeing how we can bind the Text attribute of a TextBlock

element to the property on the DP control called 'SelectedDate'.

Check out this following image in detail :-

==========================================================================================================

And if we set an initial 'DisplayDate' and bind that, we see the following at runtime, before we make any

interactive input on-screen :-

==============================================================================================================

Note above how 13.00 hrs is displayed as 1 PM.

Most often we deal with dates in collections of custom objects, se we need to extend this use ..............

Adding to a 'Data Template' :

What about if we wish to have the DP control in a list box ? Well, we can do that quite easily - check below :-

=======================================

As you can see in the above image, each item displayed in the ListBox has a DatePicker (DP)

element encapsulated in the displayed custom object.

This can be open and edited just as for stand alone elements - see below :-

======================================================

Obviously, any changes made will be saved (or remain) when the input area closes.

However, if we do not wish the dates displayed to be changeable, or editable, then we can disable the

element to look like this :-

======================================

So we can see the dates but can't change them - yes, I know, then why do we need a DP control !?

In that case, we will stick with changeable ones ;-0)

Let us look at the simple XAML script required to do this - it is within the DataTemplate - check this :-

===================================================================================================

Now the folks, we can improve on the above, lets move on ....................

Alternative Syntax - 'Data Template' specification :

Let us save some space, well a line actually, and also see with some alternative syntax we can change

and improve our item display, within the list scrolling display.

Check this out :-

==================================================================================

[ .. I will leave it up to you to work out how to get the red text in the script shown below .. ]

Yes, on the first line of our template display we have two bound data properties. The 'RUN' allows us

to make some very 'flexible' outputs.

Study the following very carefully and thoroughly :-

==================================================================================================

And of course the other related list box elements on our screen / window reflect the improvement.

Here is the control for 'Changed Items' :-

================================

Now where do we go ? Well we may loot at how to get DatePickers showing in a DataGrid control !?

I will go and investigate.

DatePicker - within a DataGrid control :

First of all we need to realise that although the DataGrid element has some built-in cell contents types,

there is NOT one specifically for picking dates.

Here is what exists already on the DP :-

=======================================

So in the above image we see we can have a CheckBox, a drop list, a Hyperlink and a Text - column.

However, for everything else we have to use the 'Template' column and built our own to suit our needs.

Here is how we go about adding a DatePicker (DP) to a data grid display.

Doing it ourselves - DP within a DG control :

If we wish to do this ourselves we could do worse than look at the MSDN advice - here is the link I used :-

http://msdn.microsoft.com/en-us/library/system.windows.controls.datagridtemplatecolumn(v=VS.100).aspx

After putting some (most?) of the script in place we get this in our exploratory DataGrid :-

=======================

The header needs changing to something appropriate to our example collection, and we need to get the binding

correct - as far as what is pointed to - property wise ;-)

Let us look at the extra script lines we have just added - lines 157 through 159 - check this out :-

==========================================================================================================

In the above image you can see that we have two templates required - one for cell display and the other

for cell editing.

Having gotten the binding right for my collection we are using, here is some better sample output :-

[ .. make sure you take full note of the two templates - display and edit .. ]

============================================================

[ .. Yes! I know the Month header text is part missing !! - I can't sort it - SORRY ! .. ]

And now we need to study the script used to do this - check below :-

====================================================================================================

Note that we seem to just get a DatePicker control when we select to edit a cell in the column called

'First Order'.

Enough fun for one afternoon, time to move on .................

See you in the next sub-section.

PHH - 23rd. & 24th. December 2013.


Events on UI elements - using in a 'basic' approach

Events on UI elements - using in a 'basic' approach

Events on UI elements - using in a 'basic' approach

 Previous topic Next topic

Even if we are guys who are aiming at using the MVVM pattern, we still need to know about events

on our XAML screens, and how we may handle these, and write methods to be associated with the

events being fired / triggered.

With MVVM we do not deal directly with events and handling, there are other ways to get what we require.

In the following image of some XAML script we line 39 contains an event association - the event name is

'SelectionChanged' and the handler method is being pointed ta via a delegate under the hood.

Check this out :-

=======================================================================================

The Delegate, or 'action pointer', associates the handler method named 'cbxRegExPatterns_SelectionChanged'

with the event. So when the event fires the method will be run.

Here below is the Properties pane showing part of the event list available on the ComboBox UI element.

Note the 'lightning' symbol edged in blue at the top right of image :-

=====================================================================================

If we double click in the empty input box we get an auto-generated method name.

Even when we have not supplied a 'chosen' name for the control we still get a result - see below :-

======================================================

And the resultant code behind is as shown next :-

============================================================================================================

Notice that the VS shell behaviour is for us to get an empty 'stub' method, into which we should add our own

extra code lines. This works for C# and Vulcan 3.

Lets now look at some working code behind - the following image shows the 'RegEx' drop list study the screen

display as it is seen at runtime :-

============================================================

So what happens when we select an item from the drop list ?

In the following image we see that two lines of .NET code 'action' have been added to the event handler method :-

===============================================================================================================

So in the above image we see some text property detail being provided to a class scoped string property called 'myRegEx'.

In fact when we get more experience we could do the same thing through data binding, and this is very much the MVVM way

of doing things.

All UI elements and controls have events which can be used. In the follow real live sample image we see that we are

using three ComboBox selection changed events and two push button click events.

Check them out :-

======================================================================================================================

Remember guys, when we get just a little bit more knowledge and experience we will start using more data binding, as

well as stop creating code behind.

However, we all need to know how the basic event handling system works for WPF and XAML.

Let move on to the next sub-section ...................

PHH - 18th. October 2013.


'UserControl' and 'ContentControl' - a good sample

'UserControl' and 'ContentControl' - a good sample

'UserControl' and 'ContentControl' - a good sample

 Previous topic Next topic

PHH - 31st. October 2013.


Tidying and Presenting - Resources, Styles & Templates

Tidying and Presenting - Resources, Styles & Templates

Tidying and Presenting - Resources, Styles & Templates

 Previous topic Next topic

One of the biggest problems when a guy comes new to XAML script, is the apparent mess and

confusion of the script itself - it seems disorganised and difficult to read and follow.

This was how I felt when I came new to XAML - and I have to admit, I did not really like it much at all :((

Since those early days (many years ago) I have changed my opinion and attitude - I realise that our

XAML script is simply as tidy as WE wish to make it.

It is up to us to make it clear, clean, and tidy.

Let us start with a working example, and then see what we can do to increasingly tidy up the script.

Take a good look at the following screen - WPF form / window :-

=======================================================================================

To create the above GUI display we are using the following XAML script - it is currently collapsed

so that we can see the 'shape' of the whole thing.

Check out below, and how all UI elements are within the one main Grid :-

[ some nesting exists, but not a lot .. ]

===============================================================================================================================

Okay then, so we know what we are faced with.

Let us focus our attention on the Resources section of the main Grid, this is where we can put details to help

tidy the 'body' of our script.

Here is how our Resources section looks at the moment - we have two data templates specified :-

=============================================================================================================

Actually, in the above image, we do not see much detail in the Resources section - we can do a lot better

than this.

Let us now add a style subsection, one for a 'ComboBox' - check this out :-

===========================================================================================

In the above image we see that we have moved four attributes / properties and the values, to the

style section in Resources for any ComboBox declared within the Grid itself.

This has had the effect of allowing us to remove these attributes from the script for the individual

UI elements - just the ComboBoxes.

Already we are starting to see order from previous chaos ;-0)

Now then, how about we do the same for the Button objects within our main Grid.

Check out the following Button related script :-

===========================================================================================

And with this style set for any Button in the main Grid we can remove and tidy script within each Button

declaration - check this out :-

========================================================================================================

Okay then folks, you are starting to get the idea, we could got on and do the same for Label - BUT - we will

see a lot of this 'stuff' done on a regular basis throughout these eNotes, so we may be better to focus on another

aspect or two of using Resources.

Scoping :

'Named' Styles :

Styles based on others :

Styles - 'Overwriting' attribute values - most local wins ! :

PHH - 18th. October 2013.


Styles - some introductory ideas

Styles - some introductory ideas

Styles - some introductory ideas

Previous topic Next topic

Let us start VERY simply.

Let us start with a new and empty Window, onto which we drag and resize a Button control

from the Toolbox.

Yours may look like mine - shown below :-

===============================================================================================

I am sure you are all reasonably familiar with the untidy sort of visual layout of script lines 6 and 7.

However, we can achieve the same attribute specification using a different syntax, and still keep the

XAML script in the body of our mark-up.

Check out the following details :-

===============================================================================================

Notice in the above script image that lines 11 to 21 do the same things as when we assign a value

to an attribute the 'basic' and untidy way ;-)

Because all of the example values above are basic, or standard types, we don't need to call upon

any more complex syntax.

One thing that does interest us however, is that we can't assign a value to the "Name" attribute this

way - check out the following :-

================================================================================================

Remember that for applying the MVVM 'pattern' we do not choose to use the 'Name' attribute. But

that has nothing to do with the reason the XAML editor won't allow it.

If we keep this applying our setters and values we will see the following :-

=============================================================================

Now then, this may remind some of you guys that the above seems very like some script sections

you have previously seen in the Resources section of a mark-up for a Window.

Let us now copy the majority of this Style and create a Style in the Windows Resources part of our

script. Check the following out carefully :-

[ .. note that the visual order of the Button images and the script lines is reversed .. ]

===========================================================================================

[ .. it makes sense that we can't applied a 'Name' value, as all Names should be unique, and Resource .. ]

[ .. Styles are for re-use, or repetitive use .. ]

In the above image, that fact that on line 7 we have not given the Style a 'key' means that it will be implicitly

applied to any Button we have in scope, and any local attribute values will 'over-rule' or 'over-ride' those

of the Style.

Hence in lines 23 & 24 we have local values to apply but all but the Margin are similar in value.

Although we can't see it they do override the Style values.

We can make a further tidying of the XAML body script by doing the following :-

====================================================================

Lets move on a pace or two .......................

Resources and Keys - applied to our Styles :

Usually when we place 'stuff' in the Resources section (or Dictionary) it is for reuse when we

choose to do so.

Quite often we don't wish to create and use an implicit Style, and so we provide a 'Key' so that we

can refer to it by this key, when we wish to use it.

Lets see how the syntax looks with a key applied - check this out below :-

=========================================================================

The highlighting above shows the newly added 'key'.

And now that we have a key we can use it as follows - check below :-

=================================================================================

In the above image we see line 24 which causes the Static resource to be used.

When we do things this way we must assign the static resources with the correct key to the

'Style' attribute - we make an association.

One Style based on Another :

Lets get Things Right ! - our Ideas of what we are doing / trying :

PHH - 27th. & 28th. November 2013.


Styles - example 1 (some Smiles again!)

Styles - example 1 (some Smiles again!)

 Previous topic Next topic

Styles - example 1 (some Smiles again!)

 Previous topic Next topic

Okay guys, we tried this under the 'Canvas' child section at the start of the eNotes - and failed.

Now we will use a suitable combination of Style and Template in our Windows Resources section.

Here is what we are after - the runtime display is on the right hand side of the following image :-

==============================================================================================================================

In the above image we see how simple and clean the body of the script can be when we use Resources correctly,

and for sensible reasons.

I think we could even make it simpler, by effectively hiding the Template association up in the resources style.

We will look at that another time, for the moment lets see what we need to do to get our three nice colourful Buttons.

Windows - Resources Section :

Into the Resources section we need to place a 'ControlTemplate' as well as an implied Button style.

Check out the following details very carefully :-

============================================================================================================

Notice above that the Style does not have a resources 'key' and so it is implicit to all Button controls.

This means that the Style is applied to the Button, and then the 'ControlTemplate' is applied too.

What we must not do is "overlap" any of the attributes, as the template ones will always prevail (win).

Notice that the design surface shows these correctly at design time, and before runtime.

Check below :-

==============================================================

Lets move on ......................

PHH - 26th. November 2013.


All 'Smiles' - or "Smiles all round!"

All 'Smiles' - or "Smiles all round!"

All 'Smiles' - or "Smiles all round!"

 Previous topic Next topic

Okay then folks, we have had a few smile, why don't we make some more - BUT - this

time allow ourselves a way to change the colours of a few attributes.

Take a look at the following 'body' script of our mark-up to see the results in the designer,

as well as the simple way we can make an improvement, before we go to add a Grid for

tidier use.

Check this out :-

=======================================================================================

The above 'body' script is simple enough to read and understand.

Here is what it produces at runtime :-

=================================================

So how do we do this ?

How do we keep a Style for a Button control, and apply a 'ControlTemplate' which can pick

up values of attributes from the control itself - those set by the Style and/or the local setting

of a control attribute ?

Let us see how this is done, and take one step at a time.

First of all let us study the script for the 'implicit' Style for any Button control on the Window.

Check this out thoroughly :-

=========================================================================================================================================

In the above image let us look at line 20, where the Background attribute on the Border object is being

bound to that property called 'Background' on the parent Control.

Notice that the fact that the two attributes being bound are both called 'Background' is my choice, it is NOT a

necessary 'thing'. We can (out of choice) bind attributes of different names as long as they have similar types.

[ .. we won't get into Converters here ..]

In order to bind from the template back to the parent we need to use a 'RelativeSource' (RS).

The syntax may at first appear 'wordy' or repetitive - BUT - it is no worse than .NET and object / property definition

syntax.

Think of the line 20 as reading .... "make an object of type RS for a specific type of 'TemplatedParent', and bind the

attribute on this called 'Background' to the attribute on the Border called 'Background'.

As you can work out for yourself, this means that with the Style attributes provide a value of 'Thistle', provided

that there is not a 'local' setting to override the Style colour.

So the following script makes 'Thistle' coloured Smiles :-

===============================================================================================

Now let us move on a step ...........

Setting local values to override or prevail :

If we supply a local value for the Background attribute on a Button, then this should now be bound

right through to the Border on our 'ControlTemplate'.

Lets try this :-

=======================================================================================================================

Yes, as far as I can prove to you with captured text and screen shots, this works as planned.

Let me try a final experiment to confirm we are doing as we think we are !

Let us try and add a 'BorderBrush' to our Border object and make it the same colour as the Foreground

of our style.

Check this out below :-

=====================================================================================================================

Well, apart from looking nice, this does seem to prove what we thought we were doing, and does just

what we though would happen.

Obviously we needed to set a 'BorderThickness' as well.

Lets move on a pace ..............

Taking the binding another level 'backwards' (from the GUI ) :

What do I mean by this ?

Well, first of all if GUI is forwards, then data and 'Model' is backwards.

So we are going to look at how data, in a bound property of a data object, can be bound to a UI control,

and then an attribute of that control be bound via a Style attribute right through to a 'ControlTemplate' attribute.

So far, as seen above, we have the 'binding chain' going from UI attribute through to CT attribute.

Now we need to go 'backwards' towards the data a step.

Let us look at some very basic .NET code which is placed in the 'code behind' section.

Although this is certainly NOT The MVVM way of doing things, it does serve a purpose of showing us what can

be done with the binding technologies.

Here are some field settings in code behind :-

============================================================

And below is what we see at runtime - check this out :-

=====================================================

Now in the XAML script mark-up file we see these three extra bindings to what we had previously.

Study these carefully :-

============================================================================

Yes, I know, the MVVM ways does not have 'Name' attribute specified, but we are using a simple

way to demonstrate 'chained bindings' - so no harm done really.

This is why lines 35 - 37 refer to the Button names for the 'DataContext' assignments.

Effectively, in the script and code above, we have lengthened the chain of binding, one property / attribute

to the next, and so on to the 'ControlTemplate' attribute which does the displaying in the UI.

So all we have to do now is change the .NET code for the coloured brushes, and we should see a

difference at app runtime - check this out :-

================================================================

PHH - 27th. November 2013.


Interaction - where to put this, how to script it

Interaction - where to put this, how to script it

Interaction - where to put this, how to script it

 Previous topic Next topic

For you and me 'Interaction' is all about using and applying MVL (MVVMLight).

I came to this whilst following Nick Friend's starter app and notes on MVL that he did for the local

VOUG meeting in Bristol - November 2013.

Basically, when we apply MVL we need to stop using the conventional XAML 'events'.

To get a similar results as when we use 'events' we need to use Commands, and then to associate

an event with a command and name (usually the convention is to add 'Command' to the name) and then

finally in the .NET code in the ViewModel to associate a handler method with Command.

This will all become clear if we step through it, one step at a time.

Lets start with looking at a single Trigger - "one trigger to one event" :-

===========================================================================================

In the script shown above we are dealing with one event of the 'TextBox' control class.

So if we have a 'TextBox' on our form then we may well need to handle multiple events.

Either way we need to set a collection of Triggers - zero, one, or more.

Lets look at a typical single 'TextBox' in the main body of our XAML script section. This actually works,

even though it was added as test script for the eNotes :-

==============================================================================================

If we read the above script it says ... make a Triggers collection of one Trigger item, for the 'TextChanged' event and

associate this with a Command called 'TextChangedCommand' in the ViewModel code.

The interaction triggers are defined for the control within which the 'nesting' takes place - in this case a 'TextBox'.

Comment for Advanced users :

When we move this script from the body to the Resources section we need to add some extra script text to get the

binding to work on a Style and for a "ControlTemplate" with 'chained' binding.

Keep this handy as it will come in VERY useful :-

================================================================================================================================

And also the single item collection of Triggers :-

=========================================================================================================================

Lets move on ...............

What are we trying to do next ? :

Well, actually, we need do nothing more if we are happy to place all the script lines in the body of the mark-up.

However, since I have seven TextBoxes on the UserControl I would like to simplify the script to read as shown below :-

==========================================================================

If this is to work we need an implicit 'Style' in the Resources section for a TextBox.

Check out the following :-

================================================================================================================

Well guys, that looks simple enough, an implicit Style for any TextBox control based on that called 'Mine555'.

So what does that ('Mine555') look like ? - check the next image :-

====================================================================================================================

Arrrh ! - that's starting to look more like it, however line 33 refers to a third Style, one with some basic settings

set out.

As you can see above, I have had to use the advanced script on lines 37/38 so that the chaining of the

data binding works at runtime.

Lets now take a look at Style 'Mine5' which is also a Resource - check this out :-

=================================================================================

Time to try and explain a thing or two about all of this so far above, but first we need to answer this below .................

Why not a Single Style and a Setter for the Triggers ? :

Since from the tags it would appear as it the 'Interaction' is a property / attribute, then it would seem a good

idea to try the 'Setter' approach - BUT - this is what the pre-compiler says :-

===========================================================

I other words the syntax show below is not going to work for us - check this out as a "non-runner" :-

===============================================================================================

However, if we can 'Set' the "ItemTemplate" property / attribute, as shown in the longer Style resource in

the following image :-

=====================================================================================================

Then there is no reason why we can't do something similar with the "Template" property as seen in the

following image - check this out :-

=========================================================================================================================

However, since 'ControlTemplate' settings can't be overridden by local ones, we need to employ binding techniques.

If we wish the Style value for a property/attribute to come through to be seen on the template, then we have to bind

the template property to the underlying Style property.

Study carefully the next image, particularly line 32 :-

===================================================================================================================================

So this simply means that the Style attribute entitled 'Text' of the parent (of the template) is bound

to the 'Text' attribute of the TextBox 'ControlTemplate'.

Apparently, according to good book source material, this is a very common thing to do with 'ControlTemplates'.

This technique allows property values to be changed in script at a Style level, and not mess around internally

with the CT script etc..

Time to move on ..............

See you in the next section.

PHH - 28th. & 30th. November 2013.


Templates - tips on working wisely with

Templates - tips on working wisely with

Templates - tips on working wisely with

 Previous topic Next topic

Eisenberg & Bennage say this :-

"WPF's templating mechanism is perhaps its most innovative feature.

[ .. possibly XAML should replace WPF .. ]

Being able to reuse control behaviour while changing the look of the control is a great example

of SRP/SoC***, and is a boon for developers.

Below is a few thoughts on how to work wisely with Templates."

*** "Single Responsibility Principle - Separation of Concerns" ***

Thoughts and Tips :

1. For anything other than a small app keep your Templates in a Separate 'Resource Dictionary' from that

used for your Styles.

Use Styles to set the Template attribute on a UI element, rather than setting the template directly 'in-line' on each

individual UI element.

The above gives more flexibility with the composition of styles and helps eliminate needless repetition.

2. Custom Controls (CC) : If you build these then strive to place as much of the CC looks as possible into a

'ControlTemplate'. This then gives future users of the (your) control the flexibility to change the look if they

so desire.

3.

5. Do NOT build specific data types into a control template.

PHH - 1st. December 2013.


Templates - for Data

Templates - for Data

Templates - for Data

 Previous topic Next topic

MSDN / SDK Help Viewer 2.0 - docs say .... "DT - describes the visual structure of a data object."

"The WPF data templating model provides you with great flexibility to define the presentation of your data.

WPF controls have built-in functionality to support the customization of data presentation.

We also have access to other data templating features, such as the selection of templates based on

custom logic and the support for the display of hierarchical data."

*** Note *** we must take care not to get keen on any aspect which will compromise our application

of the MVVM 'pattern' approach.

MVVM is more important than a few fancy extra bits of scripting !!

=======================================================================

Data templates are one of the two types of 'template' used with WPF and XAML.

[ .. so this applies to Tablet and Phone and Silverlight apps as well .. ]

The other type is the 'Control' template.

'DataTemplate's (DTs) provide a way to describe how data should be 'visualised' in terms of

UI elements.

This is NOT to be confused with deciding how to render (or format) a DateTime value, or formatting

a telephone number.

Formatting data will be done elsewhere.

"Data templates are a composition of UI elements."

Many controls have properties of type 'DataTemplate' - for example 'ItemsControl.ItemTemplate' and

'GridView.CellTemplate'.

List elements and the 'DataGrid' control are probably the most commonly used by standard guys, and these all

have an 'ItemTemplate' attribute / property.

Check out these images :-

=======================================================================================================

===========================================================================================

=============================================================================================================

========================================================================================================

As you can see in the above four image samples, there is an "ItemTemplate" for each of the list based

UI controls.

Lets move on ...............

DataTemplates are simple in nature, and idea - Easy to apply :

Okay then, the very first thing to say about DTs is that they are in essence a simple idea.

As well as being a simple and effective idea, they are also quite easy to design, create, and apply.

Most developers will need to use DataTemplates with their List and Grid controls.

DTs can make you data and app come alive ;-0)

Lets take a look at how we may enliven some of our list data - checkout below :-

============================================================================

The above image shows how some otherwise boring data may be made visually much more

interesting and engaging to the user.

Look at just one collection item - that for Paul.

We see that we have a mixture of font styles and weights and sizes.

But we also have a Border and some colours, as well as an image related directly to the item.

It may also interest you to know that the date and time are 'live' and are updated every 5 seconds.

You may also like to know that this app translates over to the Tablet (WinRT) very well.

Also, the original app was written many years ago in Vulcan and had some nice Trigger features.

I don't tend to use Triggers these days, for technical reasons (basic MVVM), and for cross platform coding.

[ .. some technologies don't support Triggers like those below .. ]

Just so you know about Triggers in WPF, in the following image I have uncommented the Trigger

lines and they are working as they originally were - study this :-

======================================================

When I last looked - some years ago - you could not do this in XAML for Silverlight.

However, lets study that part of the template which handles the main display, without the Triggers

being active.

Check out the 'DataTemplate' as included in the body of the script, within the 'ComboBox' declaration :-

===========================================================================================================================

The problem as seen with the above script image, is that the very necessary 'DataTemplate' script confuses

the reader / developer somewhat. It would help if we could remove this section to the Resources tagged section

at the top of the file.

Lets see what our 'body' script looks like when this is done - study below :-

============================================================================================

[ .. note in particular line 93 where we reference the data template .. ]

Yes, I think you will agree, it is much cleaner to read, and see what is going on with the ComboBox itself.

Now then, we need to see what we have to do to make the Resources DT (DataTemplate) available to

us and the body of our script.

Check out the following CAREFULLY :-

==========================================================================================================================

In the above image notice in particular line 11 in which we have had to specify a 'key' so that the DT can be referenced from the

body of our Window script.

I have to say, that after a few years binding my collection data to Lists and Grids, I usually place most of my DTs in the Resources

sections.

We now need to look as a related issue - that of using 'DataType'.

Lets move on .................

DataType property / attribute :

When using 'DataTemplate's we can have implicit and explicit use - like when using Styles.

So far I have shown you my preferred way of using explicit DTs and using their 'key' values with a

Static resource reference.

Let us see an implicit way of doing the same thing - just for the sake of knowing ;-0)

Below I have commented the previous script and added a new 'chunk'. Study line 54 in particular :-

=========================================================================================

In the above script we are referring to a .NET type we have created for use with our business app.

However, to be able to do this referencing we need to make sure that our script file has the suitable

namespace references available to it at the top of the file - check below thoroughly :-

================================================================================================================================

You can see in the above image that line 11 is specifying the namespace "WpfMVLstart" and that is because the

class definition for 'Customer' is within that very namespace - see below for information :-

======================================================================================

So what does this mean ? What difference do we see in our script ?

Because we have specified a DataType attribute value, then this will be implicitly applied when we

have data items of type 'Customer'.

That then means we can remove any reference to a 'key' value for the 'ItemTemplate' - checkout below :-

===============================================================================

So before we tidy our code, and remove unwanted lines, we need to do a build and run, just to

see that it still works as required - see below :-

=============================

Okay the guys, if it is all working as expected we can make our code look as seen in the next image :-

========================================================================================

Time to move on, and remember I have had a lot of GUI success using the 'key' and explicit approach to

"Data Templating", so give this method a go first.

See you in the next subsection ..........................

PHH - 29th. November 2013.


Templates - for Controls

Templates - for Controls

Templates - for Controls

 Previous topic Next topic

Okay then guys, if DataTemplates (DTs) are as easy and as straightforward as they appear, what can be

different about 'ControlTemplates' (CTs) ?

Well there are some more difficult aspects to CTs as opposed to DTs, and we need to take a step at a time.

First of all, lets see what the MSDN documentation has to say :-

=========================================================================================================================

What do we learn by reading and digesting the above details ?

Well, it would appear that we are being 'warned off' creating our own "custom controls", and that seems to square (agree) with

the book I have here in my office - which basically said " if you don't have to, then DON'T ..."

Do NOT get mixed up as I did between 'User Controls' and 'Custom Controls'. The former we can use frequently, and to

good effect.

What's the problem then ? :

Well, it seems to me that we all wish to use a larger variety of controls out of the Toolbox - BUT - we know very little, or virtually

nothing, about the existing ControlTemplates that come as default with each control.

The consequence of this lack of knowledge means that when we apply our own CT to a chosen control, we override the

default (or existing) one and don't know what we may then be missing.

For example, it is easy to see demo samples of changing the CT for a Button - however, we soon are made aware that we have

lost the Triggered 'response' when we move the mouse pointer over the Button surface, and also when we 'click'.

In the Smiley faces example this is what happened - loss of expected response.

So, without knowing what may be lost to us, I would say we need to "proceed with caution" when it comes to applying

our own CTs.

Lets see if I can capture and show some images to confirm what I have said - first a standard button :-

=================================================

And now our own Smiley - notice there is no difference :-

====================================

Yes, we can add our own Triggered response, but then we need to know more - have more experience.

Lets move on ..............

Example - 'Mouse-Over' trigger for Button :

Okay the folks, just to show you that we can add a Triggered action to a CT that we make ourselves, here

shown below is a useful example.

First we need some sample output - samples that change as I increase the number of visual changes in

the Trigger response.

Lets see some results, check these out below :-

==================================================

The above is achieved by only one property / attribute change - here it is show below :-

========================================================================================================================

As well as the obvious extra 'Triggers' section, we also need in line 22 a 'Name' value being set.

This 'Name' value is then used in the 'Setter' line of no. 39.

If we force even more changes we can quite easily get this - check it out :-

==============================================================

And now we can see the script lines which create this effect - see below :-

===================================================================================================

Now then, if we change the Window background colour to something darker, we can get this

effect at runtime :-

==================

Time to move on ...............

Which Controls can take a 'ControlTemplate' ? :

Let us try to do some experiments to solve this little puzzle.

We can use IntelliSense to help us - see below for 'ListBox' :-

=======================================================================================================

And what about a 'DataGrid' control ? :-

=======================================================================================================

Now then something different to what we saw with 'DataTemplate', lets try a 'TextBox' control :-

=================================================================================================================

It would appear that many more controls can have a CT associated with their 'Template' property / attribute, than those

which can take a data template.

But before we get the idea that all UI elements can have a CT lets try another, and common control ........

Yes, finally for now, the 'TextBlock' control :-

===========================================================================================================================

Oh! we can see that there are no 'tem..' entries in the context drop list menu.

I think we have done enough for new guys coming to XAML and WPF binding etc..

Before we leave this subsection I suggest that you get your GUI to work as MVVMLight (MVL), and

get your data and business logic structured to the MVVM 'pattern', and not worry too much about fancy

UI interactivity.

See you in the next subsection ..............

PHH - 29th. November 2013.


Resources - when & where & Dictionaries

Resources - when & where & Dictionaries

Resources - when & where & Dictionaries

 Previous topic Next topic

'Resources' is a simple idea, but the use and application of 'Resources' can become quite complex.

Most often standard guys don't use 'Resources' in a complex way. I know I don't.

However, I feel that all guys using XAML, even those coming to it new, should use 'Resources' in at least

a simple way - to keep there main, or 'active' XAML script clear, and clean to read and study.

Start out by using Resources at a screen level - Windows, Page, or 'UserControl'.

===========================================================================

Do new guys need Resources and/or Dictionaries ? :

Well, to be perfectly honest, we could probably get along OK without 'Resources' for small apps.

But quite honestly, they would have to be 'small' !

For most of us guys writing small to medium sized apps, we can probably get away with including the Resources

within the form we are creating, or using.

For many of us we can also place all our Resources at a level which is the form itself - for Window, UserControl or Page.

When we as developers move to larger apps we must start organising our Resources, and probably start to provide

a bunch on a application wide basis. So we can define 'Application Resources' in our 'App.xaml' file which exists

in all applications.

When we get really smart (and experienced) we may well wish to share Resource Dictionaries across Projects and Apps.

Lets start simple ...............

What is a 'Resource' ? :

Before diving into resource dictionaries let's first understand what the term "resource" means - when used in the context

of a resource dictionary, or in a resources section of an object in XAML.

A resource is an object declared in XAML - of type "ResourceDictionary".

Resources cover 'Styles' and 'Templates' in particular, as well as less often used 'DataObject's.

I find that in general use it is 'Style's which are most frequently used.

Here is a sample 'Style' :-

[ .. note that this is 'implicit' as it has no 'key' or identifier in line numbered 11 .. ]

==========================================================================

And now an Explicit form of the same - see below :-

=============================================================================

Lets see how to use the above ................

Applying Implicit & Explicit 'Style's :

An implicit 'Style' is used by the system on the target UI element type, but ONLY if there is

no other Explicit style specified.

The most local of any Implicit style 'wins' or takes precedent - it overrides any other.

An Explicit style is applied to a control when the 'Style' attribute has a value specified.

There are a couple of ways of writing the script to do this.

Alternative syntax for Explicit 'Styles' :-

The shorter form :-

==========================================================================

The longer form :-

======================================================================================

Although I like the longer form because it is 'less sloppy', or to me "more correct", it does make

the body of our script less clean and harder to read and follow what is been done.

Here is the script for the defined and 'keyed' style being used above :-

===============================================================================

I have added line 25 so that the image shows up better in the screen capture of the designer.

Here is a sample 'Template' :-

[ .. note DT's must have a key .. ]

====================================================================================

When defining a Style, a new 'Style' can be "BASED" on another.

Look in the Style section of these eNotes to see how this is done.

Where Can I Locate Resources? :

Resources are located in resource dictionaries. It is as simple as that !!

When we refer to a "Resources section", it is actually the Resources property (XAML / WPF) which is of type "ResourceDictionary".

When we add resources to the Resources property, we are actually adding them to a "ResourceDictionary" exposed by the object.

So we generally see a set of items in a collection - the collection items are children of the "ResourceDictionary".

*** Note ***

The Resources property is defined on FrameworkElement (FE) and is inherited from ANY object that has FE in its inheritance hierarchy.

This means that resources can be located on Windows, UserControls, Grids, Buttons, TextBoxes, ListBoxes, etc., etc..

However, resources can also be located in a "ResourceDictionary" XAML file - external to the UI element script file.

*** NOTE *** this is all much easier to do (copy and adapt) than it is to describe in words !!!

What is the Point of "Resources" and their use ? :

There are at least two main reasons for us developers to use Resources.

Tidy - reduce excess scripting - improve readability. This is a GOOD idea for the new guy !!

Allow a consistency of 'look' and 'design style' to more than one screen - even the whole application, or even suite of apps.

Also there is a third for advanced developers, and that is for defining and changing application 'skins'.

Think of a 'skin' as being a whole bunch of Resources, probably in multiple dictionaries. Swapping one bunch (or Theme)

for another, is said to be selecting a different 'skin'.

If you are at all new to XAML I would suggest you leave Themes and skins for another day - and make that day just a little

way into the future ;-0)

Scoping - within Application / Window / 'UserControl' / Page :

One thing we have to get right, and understand, right from the word 'go' when using 'Resources', is scoping.

We need to understand at which levels of 'scoping' we have to provide resources, as well as understand how scoping

'rules' apply, when it comes to control and element 'styles' overriding' or overwriting existing ones.

Don't put UI element styles in the App.xaml file as application resources, when in fact they will only apply to one screen,

or even part of a screen, or individual Grid.

Wide scope or Narrow scope ? :

Keep you scope as 'close' or as 'arrow' as possible - only widen what you do if you find yourself repeating styles and templates

in more than one place or file.

Think of how your approach the scoping of variables - keep and definition close to where it is used and required.

Checkout the next small sub-section .............

Look for a Resource - what happens :

Lets see what MSDN has to say - check this out below :-

==========================================================================================================

Implicit and Explicit Styles:

How we scope is in some ways also related to whether we use Implicit and/or Explicit styles.

We are more likely to define an implicit Style at a higher level (window or app) and then have an explicit style

applied when we require it.

However, it seems as though this aspect of XAML design is quite personal, and vary a lot from guy to guy.

I suggest to all that CAUTION should be applied here.

There are many more sides (aspects) to learning and using XAML then going overboard about styles, resources,

and dictionaries.

I suggest after script tidying we do as little as possible with RDs (Resource Dictionaries) until we master the

basics (fundamentals) of MVVM with MVL (MVVMLight from GalaSoft).

Separately in Dictionaries :

Resource Dictionaries are a powerful feature in XAML / WPF that enable developers to organize and

consume reusable resources.

We can make a RD file as shown below :-

===================================================================================================================

Usually if developers are using one RD they are most likely to be using a few such files.

Keep your files as short and as well organised (structured?) as possible.

Making and Using a "Resource Dictionary" :

[ .. Creating and Consuming RDs .. ]

After having made a folder in the SE pane for our dictionaries (here I have ' rOurDictionaries' ) :-

=====================================

we can bring up the context menu (right mouse click) and add a new RD if we so choose.

Check this out for details :-

=================================================================================

The 'Add New Item' dialog screen looks as follows :-

==========================================================================================================================

This provides a new file within the folder as seen below :-

=====================================

Whatever styles and templates we place in this new file, we can refer to it from the App.xaml file as shown below :-

==============================================================================================================================

The above script would mean that all the contents of this file - a resource dictionary - is available across our whole application.

==========================================================================================================================

==========================================================================================================

Remarks from the SDK docs. :

==================================================================================================================

External Dictionaries :

PHH - 2nd. December & 14th. 2013.


Example one - Tracking Changes

Example one - Tracking Changes

Example one - Tracking Changes

 Previous topic Next topic

Okay folks, we are going to see in this section how we may place all of our Styles and Templates outside

of the project GUI script files and the App.xaml file.

By placing S&T details in a separate file (or three) we can then easily reuse these S&T details in other

projects - related or just similar.

Here is the image of a working application :-

======================================================

Any script lines defining Styles and Templates (S&Ts) has been removed from both the App and screen XAML files.

Check out the following App file for the above running project :-

===========================================================================================================

As you can see above the lines 8 and 9 reference the two external files.

Let us see the image of the SE pane structure of our solution, after one file was added,

and just before the second one was added :-

========================================

So let now try to add the second of these two resource files - check this out :-

===============================================================================

And after we make the second file, and before we re-script the correct resource 'pointers' we

can see below that the actual screen / UI display goes absolutely 'mad' - chaos !

==========================================================================================================================================

Above is file 'one' and below is the detail of file 'two' :-

====================================================================================================

And we do probably need a clearer look at the file called 'ResDictOne' - check this carefully :-

===========================================================================================================

For our test example, now that we have changed our App.xaml file to point at the correct RD's we can remove

all other Resources section at the head of our screen XAML files.

In the following image the lines 7 -46 have been commented out :-

=========================================================================================================

PHH - 15th. December 2013.


Example two - 'Class Library' of RDs

Example two - 'Class Library' of RDs

Example two - 'Class Library' of RDs

 Previous topic Next topic

PHH - 18th. December 2013.


Preparing the GUI using 'Containers and Grids'

Preparing the GUI using 'Containers and Grids'

Preparing the GUI using 'Containers and Grids'

 Previous topic Next topic

PHH - 16th. October 2013.


without 'Containers and Grids' - free placement

without 'Containers and Grids' - free placement

without 'Containers and Grids' - free placement

 Previous topic Next topic

=========================================================================================================

===========================================================================================================================================================

PHH - 16th. October 2013.


our use of the Grid

our use of the Grid

our use of the Grid

 Previous topic Next topic

PHH - 16th. October 2013.


what are 'Containers' !?

what are 'Containers' !?

 Previous topic Next topic

what are 'Containers' !?

 Previous topic Next topic

PHH - 16th. October 2013.


Suitable custom classes for 'Binding'

Suitable custom classes for 'Binding'

Suitable custom classes for 'Binding'

 Previous topic Next topic

When we come to 'Data Binding' within XAML app scripting and .NET coding, the first and most important

thing to do is to create our custom / business classes correctly.

If we do things right, then any changes to properties within our custom objects, will be automatically shown

or displayed in the UI surface at runtime.

Put quite simply, all our business classes MUST 'implement' the "INotifyPropertyChanged" interface.

Check out the following image :-

===============================================================================================

The effect of this is quite simple. If we get our coding right, then at runtime, any change in a value of a property

will be reflected in the GUI display on screen, immediately.

The change in value may be brought about in either an interactive way or in changes to the code values behind the window

or form (or Page).

If we add a suitable line to our directives, at the top of the code file, we can do it as shown below :-

========================================================

And now that we have the suitable namespace referred to in our directives, we can simplify our code, and

make it look a lot clearer and cleaner - see below, in the following two images :-

===============================================================================

and the method itself can be simplified :-

============================================================================================

It seems more than likely that MOST of our properties in a custom class, or business class, will

need to have their values 'tracked' and any changes causing a 'notification'.

One side effect of Data Binding is to reduce the number of Events we create, as developers. So the

eventing 'system' is partly relieved !

A further benefit is that we can then employ the MVVM approach by using a 'pattern' of development

which takes this even further. More on that in later sections.

Short Summary :

Get all your business and custom classes set up as above, and they can then be used with, and without,

the MVVM 'pattern'.

We can even partly apply MVVM, by just getting a single object constructed which will bind to a single

Window / Form - this is called the 'View'.

This single object is made up from single business objects, as well as collections of custom objects.

Such a single binding is called 'loose coupling'.

PHH - 20th. October 2013.


Tracking changes - seeing changes on the GUI

Tracking changes - seeing changes on the GUI

Tracking changes - seeing changes on the GUI

 Previous topic Next topic

When we are developing apps which use 'Data Binding' we need to keep a couple of things in mind

at all times we are creating XAML script and .NET code.

Property Values :

Collection Members (items) :

PHH - 23rd. October 2013.


a typical 'Binding' class - 'Person'

a typical 'Binding' class - 'Person'

a typical 'Binding' class - 'Person'

 Previous topic Next topic

==========================================================================================================

===================================================================================================

==================================================================

===============================================================

============================================================================================================================

====================================================

===========================================================================================================

===============================================================================

====================================

==========================================================================================================================

===================================================================================================================================

==============================================================================================

=========================================================================================

PHH - 20th. October 2013.


working code and script

working code and script

working code and script

 Previous topic Next topic

===================================================================================
CLASS Person IMPLEMENTS System.ComponentModel.INotifyPropertyChanged
// ----- Fields -----
PRIVATE _person AS System.String
PRIVATE _address AS System.String
PRIVATE _DoB AS DateTime
PRIVATE _phone AS System.String
// ----- Events -----
event PropertyChanged as System.ComponentModel.PropertyChangedEventHandler

//----- Methods -----
constructor()
super()
self:Initialize()
return

constructor(cP as string, cA as string, dtDoB as DateTime, cPH as string)
super()
self:Initialize()
/* self:Person := cP
self:Address := cA
self:DoB := dtDoB
self:Phone := cPH*/
self:_person := cP
self:_address := cA
self:_DoB := dtDoB
self:_phone := cPH
return
//------------------------------------------
protected method Initialize() as void
self:Person := ""
self:Address := ""
self:DoB := DateTime{1900,01,01}
self:Phone := ""
return

protected method OnPropertyChanged(name as string) as void

local propertyChanged as System.ComponentModel.PropertyChangedEventHandler
propertyChanged := self:PropertyChanged
if (propertyChanged != null)
//
propertyChanged:Invoke(self, System.ComponentModel.PropertyChangedEventArgs{name})
endif
return

static method GetPersonList() as List<Person>
local implied aListP := List<Person>{}
aListP:Add(Person{"Adam Savage","19 Upwards CRescent",DateTime{2000,10,10},"01633 101010"})
aListP:Add(Person{"Jackaline","13 Front Street",DateTime{2001,02,02},"01633 345876"})
aListP:Add(Person{"Adrianne","26 Back Street",DateTime{2003,03,03},"01633 3334455"})
aListP:Add(Person{"Geraldine","39, Side Alley",DateTime{2004,04,04},"01633 667788"})
aListP:Add(Person{"Frederick","2 Down Close",DateTime{2005,05,05},"01633 221133"})
aListP:Add(Person{"Susanah","53 Main Street",DateTime{1997,07,07},"01633 772377"})
return aListP

//----- Properties -----
property Person as string
get
return self:_person
end get
set
self:_person := value
self:OnPropertyChanged("Person")
end set
end property

property Address as string
get
return self:_address
end get
set
self:_address := value
self:OnPropertyChanged("Address")
end set
end property

property DoB as DateTime
get
return self:_DoB
end get
set
self:_DoB := value
self:OnPropertyChanged("DoB")
end set
end property

property Phone as string
get
return self:_phone
end get
set
self:_phone := value
self:OnPropertyChanged("Phone")
end set
end property

END CLASS

===================================================================================
#using System
#using System.Collections.Generic
#using System.Linq
#using System.Text
#using System.Windows
#using System.Windows.Controls
#using System.Windows.Data
#using System.Windows.Documents
#using System.Windows.Input
#using System.Windows.Media
#using System.Windows.Media.Imaging
#using System.Windows.Navigation
#using System.Windows.Shapes
BEGIN NAMESPACE Vulcan3ConsumerOfLINQ
partial class Cologne3 inherit Window

public aListCP as List<Person>

constructor()
super()
InitializeComponent()
self:Initialize()
return

method Initialize() as void
local implied aList := List<string>{}
aList:Add("Elizabeth")
aList:Add("William")
aList:Add("Richard")
aList:Add("Benjamin")
aList:Add("Franklin")
self:lbxFromCode:DataContext := aList
//-----------------------------------
//self:BindCustom()
self:aListCP := Person.GetPersonList()
self:lbxCustom:DataContext := self:aListCP
return

private method pbMakeCodeChange_Click( sender as System.Object, ;
e as System.Windows.RoutedEventArgs ) as System.Void
foreach p as Person in self:aListCP
if p:Person == "Jackaline"
p:Person := "Justin Change"
endif
next
return
end class
===================================================================================

PHH - 20th. October 2013.


a typical 'Customer' class

a typical 'Customer' class

a typical 'Customer' class

 Previous topic Next topic

In this sub-section I will develop and discuss a 'Customer' class which I have used previously in

a good example of an 'MVL' (MVVMLight) application.

This class seems to work well, does all I require of it, and 'DataBinding' with it seems to feel RIGHT !

Here is an image of the MVVM application at runtime, a bunch of Customer objects are held in a

collection which is bound to the ListBox UI element (control) on the left hand side (LHS).

Checkout the details :-

==========================================================

In the above image we see two lines of text for each item in the collection.

Let us start our study of the Vulcan .NET code required by checking out the required Namespaces :-

==================================================================================================

As you can see above I find it helpful to sometimes add a comment to tell me why a particular namespace

is needed.

Okay then guys, lets work our way through the necessary parts of our class definition.

Let us start with a very important part, the private fields which are to hold the data values from our public

properties (we will see these later).

Lines 15 to 22 below are our fields, and I follow a common practice of underscore and small first character :-

[ .. small reads as 'lower case' to some guys .. ]

===================================================================================

So the above field values are only available to our class code.

Lets now move on to see the Event and Constructor parts :-

[ .. the constructors are very much a personal choice 'thing' .. ]

=============================================================================================================================

Since the above detail is pretty commonplace lets move to the VERY important public property definitions.

Checkout the following, before we see some specific details for one or two of them :-

=============================================================================

Note above that the names are related to the fields by removing the underscore and capitalizing the first character (letter).

Before we look at property details, lets finish the overview 'look' by checking out a few collapsed methods :-

=====================================================================================================

Yes, I know, the last method to notify changes in properties is VERY important, as so here it is expanded :-

===========================================================================================================

Now then, if we look at the details of a property, we see that we have used this method as an important part

of our 'set' section - check it carefully :-

=====================================================================

Above, we need to supply the text name of the property being updated, or changed. Note the case is important

to get right. All the properties follow a similar pattern, or template, however the type is likely to change from

one going to another.

Study this carefully :-

====================================================================

The above example of one of our properties has the most 'different' data type, the rest are simple numerics,

string, and logic.

One interesting extra to many common class definitions is the inclusion of a 'Clone' method. See below :-

=====================================================

Line 13, at the head of this section, included 'ICloneable' in the implementation list.

This means that we have to provide this method to satisfy the requirements of the interface.

We will not say a lot about why we have done this, expect to say that it is a useful way of being able to

take a selected collection item and display a cloned version of the item in-focus, so that interactive

editing does NOT destroy existing data before acceptance by a button click.

So then, if all that we have done is pretty routine and common, what could we possible do extra, or

differently, so as to give us more features and flexibility ?

Possible Improvement ? :

Well, one thing that any custom class can do with is a 'ToString' method. Check out a simple one below :-

===============================================================================

Having provided this simple extra method, it means that a collection of Customer items will show up

in the UI in a meaningful way - check the following image :-

==========================

So if it is as simple as that then lets improve it a little - checkout this :-

========================================================================================================

Which looks at runtime like that shown below :-

===========================

Okay then, so what do we see / get when we neglect to provide a 'ToString' method ?

Here is what we see at runtime :-

=============================

Yep! I have seen a few of these types of list and grid displays in my research ;-0)

After we have looked at the data parts of our custom class we can revisit the topic of displaying

collection items, but by using the more flexible 'DataTemplate' approach.

Lets move on to see what we can often add to our custom classes, in the way of data values in our items.

Handling the Data Values :

Particularly while learning XAML and WPF, and creating demo and test applications, we often need to have a quick

and handy way of grabbing hold of a sample collection of items of the class in focus.

Here is a way I use a lot - copied from others I have to say :-

=================================================================================================================================

Note above that we first make a List<T> and then from that we make an ObservableCollection<T>.

We only need use the collection if we are using the data in such a way that collection items can get

added or removed (or inserted) in any way.

If our list to be displayed is to be static in nature, then the List<T> will do for binding.

Here are a couple of code images where this is done :-

==========================================================================================================================

[ .. the full naming below, is unnecessary if we get our #using directive section correct .. ]

=============================================================================================================================

And finally, we see code where line 49 shows the ONE line of 'binding'.

This is the line on which the 'SUPER' object is bound to the 'UserControl' (equivalent to a Window).

So all the data properties on this Super Object are available for binding to UI elements on the UC itself.

Check out these details :-

==========================================================================

Lets move on to something a little more colourful and visual ;-0)

Let us look at a way I prefer to use to display my list / collection items in my lists and grids.

Lets take some time out to study 'DataTemplate' possibilities.

My Preferred way to Display - using a 'DataTemplate' :

Let us first look at a sample display, one that was NOT done using the simple 'ToString' method.

Check this below :-

============================

So how do we get three separate data property items into one list display line ?

Here is what we can do in our XAML script :-

===========================================================================================================

Because we have separate data values making 'Run' items we can set various other properties on the 'Run',

such as fonts, font properties, colours, etc., etc..

Here below is what we see from the script shown above after it has be modified and improved :-

==================================

Notice in the above image that we now have two lines to each collection item entry.

We can study the extra details in the next image seen below :-

===========================================================================================================

Yep! a VERY flexible way to present collection item data values.

Time to move on.

See you in the next sub-section topic ...........................

PHH - 10th. & 11th. March 2014.


working code and script

working code and script

working code and script

 Previous topic Next topic

//----- Customer.prg -----
#using System
#using System.Collections.Generic
//----- added for LINQ -----
#using System.Data.Linq.Mapping //----- needed for Table & Column .....
#using System.Collections
#using System.Collections.ObjectModel //----- ObservableCollection .....
#using System.ComponentModel //----- INotifyPropertyChanged .....

BEGIN NAMESPACE WpfMVLstartVN

[Table(Name:="Customers")];
class Customer implements ICloneable, INotifyPropertyChanged
//----- Fields
private _contactId as Long
private _creditLimit as double
private _customerId as Long
private _firstName as string
private _firstOrder as System.Nullable<DateTime>
private _isLocal as Logic
private _lastName as string
private _salutation as string

//----- Events
Event PropertyChanged AS PropertyChangedEventHandler

//----- Methods -----
constructor()
super()
self:Initialize()
return

constructor(nI as long, cS as string, cF as string, cL as string, dtFO as System.Nullable<System.DateTime>, lL as logic, nCL as double)
super()
self:CustomerId := nI
self:Salutation := cS
self:FirstName := cF
self:LastName := cL
self:FirstOrder := dtFO
self:IsLocal := lL
self:CreditLimit := nCL
//-----------------------
self:Initialize()
return

constructor(nI as long, cS as string, cF as string, cL as string, lL as logic, nCL as double)
super()
self:CustomerId := nI
self:Salutation := cS
self:FirstName := cF
self:LastName := cL
self:IsLocal := lL
self:CreditLimit := nCL
//-----------------------
self:Initialize()
return

virtual method Clone() as Object
return Super:MemberwiseClone()

static method GetaBunchOfCustomers() as List<Customer>
// ------- getting a 'NULL' ---------
local oNDT as Nullable<DateTime>
oNDT := Nullable<DateTime>{} //----- without a value ------
//------------------------------------------------------------
local aList as List<Customer>
aList := List<Customer>{}
aList:Add(Customer{1, "Sir", "James", "Bolam", DateTime{2004, 01, 17}, true, 0})
aList:Add(Customer{2, "Miss", "Mary", "Malone", DateTime{2006, 03, 11}, false, 125})
aList:Add(Customer{3, "Mr", "John", "Parker", System.DateTime{2005, 05, 23}, true, 250})
aList:Add(Customer{4, "Mrs", "Bev", "Frances", System.DateTime{2008, 9, 7}, true, 180.13})
aList:Add(Customer{5, "Prof", "Nick", "Friend", System.DateTime{2007, 11, 2}, true, 90})
//------------------------------------------------------------
aList:Add(Customer{6, "Mr", "Paul", "Piko", oNDT, false, 0})
//aList:Add(Customer{6, "Mr", "Paul", "Piko", null, false, 0}) //----- can't do like this !!!
//------------------------------------------------------------
aList:Add(Customer{7, "Dr", "Dan", "Logan", oNDT, false, 350})
aList:Add(Customer{8, "Ms", "Laura", "Hepburn", System.DateTime{2013, 4, 0x18}, true, 50.13})
aList:Add(Customer{9, "Dr", "Mike", "Stein", oNDT, false, 150})
aList:Add(Customer{10, "Mr", "Ben", "Hepburn", System.DateTime{0x7dc, 1, 14}, true, 0.13})
aList:Add(Customer{11, "Dr", "Paul", "Ryan", System.DateTime{0x7dd, 9, 4}, true, 190})
aList:Add(Customer{12, "Mr", "Willie", "Moore", System.DateTime{0x7db, 6, 6}, false, 450})
return aList

static method GetCustomerCollection() as ObservableCollection<Customer>
return ObservableCollection<Customer>{GetaBunchOfCustomers()}

method Initialize() as void
return

method NotifyPropertyChanged(propertyName as string) as void
if (self:PropertyChanged != null)
//
self:PropertyChanged:Invoke(self, PropertyChangedEventArgs{propertyName})
endif
return

//----- Properties -----
property CreditLimit as real8
get
return self:_creditLimit
end get
set
self:_creditLimit := value
self:NotifyPropertyChanged("CreditLimit")
end set
end property

property ContactId as Long
get
return self:_contactId
end get
set
self:_contactId := value
self:NotifyPropertyChanged("ContactId")
end set
end property

property CustomerId as Long
get
return self:_customerId
end get
set
self:_customerId := value
self:NotifyPropertyChanged("CustomerId")
end set
end property

property LastName as string
get
return self:_lastName
end get
set
self:_lastName := value
self:NotifyPropertyChanged("LastName")
end set
end property

property Salutation as string
get
return self:_salutation
end get
set
self:_salutation := value
self:NotifyPropertyChanged("Salutation")
end set
end property

property FirstName as string
get
return self:_firstName
end get
set
self:_firstName := value
self:NotifyPropertyChanged("FirstName")
end set
end property

property IsLocal as Logic
get
return self:_isLocal
end get
set
self:_isLocal := value
self:NotifyPropertyChanged("IsLocal")
end set
end property

property FirstOrder as Nullable<System.DateTime>
get
return self:_firstOrder
end get
set
self:_firstOrder := value
self:NotifyPropertyChanged("FirstOrder")
end set
end property

end class

end namespace //----- WpfMVLstartVN -----

=========================================================================

<!--<DataTemplate DataType="{x:Type local2:Customer}">
<TextBlock FontWeight="Normal">
<Run Text="{Binding Path=Salutation}" FontWeight="Bold" Foreground="Red"/>
<Separator/>
<Run Text="{Binding Path=FirstName}" Foreground="Blue"/>
<Separator/>
<Run Text="{Binding Path=LastName}" FontStyle="Italic" Foreground="Green"/>
<LineBreak/>
<Run Text="{Binding FirstOrder}" Foreground="Purple"/>
</TextBlock>
</DataTemplate>-->

=========================================================================


a working 'ProductRange' ViewModel class

a working 'ProductRange' ViewModel class

a working 'ProductRange' ViewModel class

 Previous topic Next topic

=========================================================================

==================================================================================

PHH - 6th. November 2013.


Adding the use of 'ObservableCollection'

Adding the use of 'ObservableCollection'

Adding the use of 'ObservableCollection'

 Previous topic Next topic

PHH - 6th. November 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

==================================================================================

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//------------------------------------------------------
using System.Collections;
using System.Collections.ObjectModel; //----- ObservableCollection .....
using System.ComponentModel; //----- INotifyPropertyChanged .....

namespace WpfControlLibrarySwap.SupportingClasses
{
public class ProductRange : INotifyPropertyChanged
{
//----- fields ['private' by default] -----
string _range;
Boolean _lQuality;
Boolean _lLongShelfLife;
Boolean _lGoodPrice;
Boolean _lStacksWell;
DateTime _dtIntroduced;
List<string> _aListProdItms;

//----- events -----
public event PropertyChangedEventHandler PropertyChanged;

//----- properties -----
public string Range
{
get{ return _range; }
set { _range = value; NotifyPropertyChanged("Range"); }
}

public Boolean lQuality
{
get{ return _lQuality; }
set { _lQuality = value; NotifyPropertyChanged("lQuality"); }
}

public Boolean lLongShelfLife
{
get { return _lLongShelfLife; }
set { _lLongShelfLife = value; NotifyPropertyChanged("lLongShelfLife"); }
}

public Boolean lGoodPrice
{
get { return _lGoodPrice; }
set { _lGoodPrice = value; NotifyPropertyChanged("lGoodPrice"); }
}

public Boolean lStacksWell
{
get { return _lStacksWell; }
set { _lStacksWell = value; NotifyPropertyChanged("lStacksWell"); }
}

public DateTime dtIntroduced
{
get { return _dtIntroduced; }
set { _dtIntroduced = value; NotifyPropertyChanged("dtIntroduced"); }
}

public List<string> aListProdItms
{
get { return _aListProdItms; }
set { _aListProdItms = value; NotifyPropertyChanged("aListProdItms"); }
}

//----- constructors -----
public ProductRange()
{
this.aListProdItms = new List<string>();
}

//----- methods -----
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//---------------------------------------------------------------------------

//----- static methods -----
public static ProductRange PR1()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Boxes :";
oPR.lGoodPrice = true;
oPR.lLongShelfLife = true;
oPR.lQuality = false;
oPR.lStacksWell = false;
//------------------------
oPR.dtIntroduced = new DateTime(2005,05,17);
//-------------------------------------------
oPR.aListProdItms.Add("Short, high sides");
oPR.aListProdItms.Add("Narrow, low sides");
oPR.aListProdItms.Add("Short and Narrow");
oPR.aListProdItms.Add("Long and Wide");
oPR.aListProdItms.Add("Wide, high sides");
return oPR;
}
public static ProductRange PR2()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Containers :";
oPR.lGoodPrice = false;
oPR.lLongShelfLife = true;
oPR.lQuality = true;
oPR.lStacksWell = false;
//------------------------
oPR.dtIntroduced = new DateTime(2007,07,27);
//-------------------------------------------
oPR.aListProdItms.Add("Short, hard tops");
oPR.aListProdItms.Add("Narrow, soft sides");
oPR.aListProdItms.Add("Hard all round");
oPR.aListProdItms.Add("Open top");
oPR.aListProdItms.Add("Closed top");
return oPR;
}
public static ProductRange PR3()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Sacks & Bags :";
oPR.lGoodPrice = false;
oPR.lLongShelfLife = false;
oPR.lQuality = false;
oPR.lStacksWell = true;
//------------------------
oPR.dtIntroduced = new DateTime(2003,09,22);
//-------------------------------------------
oPR.aListProdItms.Add("Deep & Wide");
oPR.aListProdItms.Add("Wide but short");
oPR.aListProdItms.Add("Tops narrow");
oPR.aListProdItms.Add("Tops very Wide");
oPR.aListProdItms.Add("One inside another");
return oPR;
}

}
}
==================================================================================

==================================================================================

==================================================================================

==================================================================================

PHH - 6th. November 2013.


Collections suitable for 'Binding'

Collections suitable for 'Binding'

Collections suitable for 'Binding'

 Previous topic Next topic

When we are dealing with 'Data Binding' of 'collections' to our GUI Window or Form, we really need

to know just what type of collection class we are discussing.

Over the years while coding in .NET from version 2 up to 4.5 we seem to have had many types of

collection. A number of different classes.

However, the 'good news' seems to be that we can do just about everything we may wish to do with

'Data Binding' in XAML using just two types, 'List<T>' and 'ObservableCollection<T>'.

What is more, an 'ObservableCollection<T>' (OC) can be instantiated from an existing 'List<T>' object.

So in many ways we can think of an 'OC' as a List<T> with a wrapper around it.

Below we see the namespace required :-

==================================================================================

And using the Object Browser we see that the 'System' dll is the assembly in which it is to be found :-

================================================

Note that there is also a Read/Only form, but we will leave that for now.

So we can actually write a new static method to create an OC which is made from a List<T>.

Checkout the following :-

============================================================================================================================

And without a lot of effort we can use the full OC in our first ListBox as seen below :-

==============================================

So what exactly have we had to do to bind our 'ObservableCollection' ?

below is shown some code which has been suitably amended, check it out :-

============================================================================================

This change above means that we also need a changed, or amended, constructor for the 'MixedGuy3' class :-

=================================================================================================================

And look towards the bottom of the above code to see line 106 where we have the extra property required.

And finally, we have to view the XAML script to see a small change there also :-

============================================================================================

Yep! so the observable collection is now bound and shown.

So now you have seen an OC bound to a list UI element.

Time to move on, in the sub-sections of this main section we will see just what OCs can do for us, and

why we need List<T> collections as well as ObservableCollections<T>, and even one other type, that

of 'CollectionViewSource' as well.

PHH - 16th. October 2013.


List<T> class

List<T> class

List<T> class

 Previous topic Next topic

From my experience using XAML, WPF and 'Data Binding', as well as LINQ in C#, this class is probably

the most used class in my code.

I suggest you get VERY familiar with it and its use in WPF applications - as well as WinRT and Phone 8 apps too.

Here is what the SDK in Help Viewer 2.0 has to say :-

==========================================================================

Here it is in a more readable format :-

================================================================================================================

In my book, strongly typed lists are the way to success ;-0)

Read on for some extra general information :-

==================================================================================================================================

Stick with List<T> and don't use the 'ArrayList' class - there are a few benefits I won't go into now.

One is much 'newer' or modern than the other - that is good reason in itself.

Here is another :-

==========================================================================================================================

And for macho freaks and nerdy types check this out below :-

==========================================================================================================================

So there you have it !

Here is an example of using a simple business class - below we add some manually specified items :-

================================================================================================

Most often I tend to place custom (or business) objects into my lists. Although they can take any

type of object it is best to stay clear of simple data types like strings and ints - simply because at

other stages of your app development you may wish to do binding and much more, AND, I have found

that classes I define myself always work, and are often easier to get working (the correct syntax) than

when using strings and things ;-0)

Her is my simple business class :-

===================================================================

And here is a piece of script to place a suitable ComboBox in my mark-up :-

=========================================================================================

Notice we need a data template on line 40 above, and this is seen in the next small image :-

======================================================================

There are other ways of binding more than one property to a single looking display element, but

this will do for now.

Note also that we need to have the right Namespace reference in the directives section at the head

of our code file - check this out :-

============================================================================================

Finally, a VERY useful feature indeed - a typed List can be used to instantiate an OC or (ObservableCollection).

Effectively, this puts a wrapper around the List<T> and allows us to then track changes in the collection object.

Check out this .NET code for making an OC - so instead of binding the UI ComboBox to a List<T> we are

binding it to an ObservableCollection <T> :-

===================================================================================================

Yep! easy and very effective.

Time to move on ...............

PHH - 22nd. October 2013.


ObservableCollection<T> class

ObservableCollection<T> class

ObservableCollection<T> class

 Previous topic Next topic

Here is what the Microsoft SDK guys have to say :-

===================================================================================================================

You may remember that in order to get our object properties showing correctly and immediately they were changed in

value, we used the INotifyPropertyChanged event and interface, well we have something similar which helps us see

and keep a track of changes in our collections.

If we use the 'ObservableCollection' class we have 'INotifyCollectionChanged' to help us keep track of items in the collection.

So if we are to add or remove collection items via code (or other) then we need this interface / event to help us out.

Here are some more SDK remarks and comments :-

==========================================================================================================================

===================================================================================================================

=================================================================================================

==============================================================================================================================================

=============================================================================================================

PHH - 21st. October 2013.


CollectionViewSource

CollectionViewSource

CollectionViewSource

 Previous topic Next topic

This class is VERY useful to guys wishing to code in Vulcan.NET as we can use it with collections supplied by

a Data Access Layer which is a C# class library and based on LINQ technology.

'CollectionViewSource' (CVS) can allow us to have a 'View' wrapper around our collection which allows us to Sort, Filter,

and Group items in the collection on various properties of the item class.

Here is what Microsoft guys have to say :-

==========================================================================================================================

Now that we have some idea of what we are dealing with in a CVS we can see some .NET code which uses and applies

this class for showing in list controls on the GUI.

Check out the following images :-

=====================================================================================

With the correct namespace reference in place we can instantiate a class object as follows :-

==========================================================================================

Note above that the CVS is wrapped around a List<Customer> object.

And the delegate method to support the code in line 168 is as follows :-

===================================================================================================

The above code is just for a filter condition, we can see Sort and Group later on.

Here is the runtime output to study thoroughly - note selections have been made in all drop list controls :-

=======================================================================================================

And, as can be seen above, only one customer exists with an upper case 'B' in their surname.

Here is an alternative filtering, on 'FirstName' property and 'n' or 'k' in the text string - case sensitive

of course :-

=======================================================================================================

*** Remember *** we can have numerous list controls showing different 'Views' (CVS) all which are based

on the same underlying collection.

Any missing items in the displayed 'View' are still within the collection, they are just not visible, or shown.

PHH - 21st.& 22nd. October 2013.


Enums - select from drop list

Enums - select from drop list

Enums - select from drop list

 Previous topic Next topic

It is often VERY convenient from interactive GUI screen to be able to select an 'enum' from

a drop list or fixed list box.

In fact this is very easy to do, and we must NOT be tempted to make a sting array as a quick fix.

Below is a sample drop list (combo box) of mine in a C# app. Study my SE pane detail as well as

the runtime UI display :-

=====================================================================

The .NET code for this is seen for both C# and Vulcan 3 in the following images :-

C# : Vulcan.NET :

===========================================================================================================

If we stick with the syntax variation as seen above, we can try to place the 'enum' objects into

a List and a list control in a few ways - some are smarter than others ;-)

Here is a start, even though it is long-winded :-

==============================================================================================

Well, a bit of a 'hack', but at least we are storing actual 'enums' in the list !

Once we have a list we can then bind it to a suitable UI control - in the typical XAML binding way :-

=========================================================================================

Notice in the above image that line 60 shows the less smart way to do things, whereas line 63 uses

a much better way - and that improved approach is seen in the next image :-

===============================================================================================

So it would appear that in C# or Vulcan 3, we can us the above 'GetValues' way on any 'enum' we

create, or can get our hands upon - system and third-party as well.

Time to move on ......................

PHH - 22nd. October 2013.


Tracking 'Changes and Edits' - Collections

Tracking 'Changes and Edits' - Collections

Tracking 'Changes and Edits' - Collections

 Previous topic Next topic

If we use the 'ObservableCollection' (OC) class this has built-in mechanisms to help us developer guys

track changes to the collection.

The OC class implements the interface 'INotifyCollectionChanged' and the SDK docs say this :-

"Represents a dynamic data collection that provides notifications when items get added, removed,

or when the entire list is refreshed."

However, it also implements "INotifyPropertyChanged" and the SDK shows that the two events for 'OC'

are as follows :-

======================================================================================================

Now when we read the above details we see that we ought to be able to do just about everything we need with

regard to tracking changes in our collection, and its items - BUT - if we do not define out item class fully, or

correctly, then the property changes on any item will not cause the 'PropertyChanged' event to fire when we

expect it to.

There are huge numbers of posts found by Googling which show that guys out there get MANY issues because

the item class is not defined / declared in a suitable manner.

In this section and its child sub-sections, we will see just how to code things such that everything works as we

would hope it to. For the collection changes and the collection item property edits.

However, we will take a step at a time, and create examples to show exactly how to use OCs for the common

case where we have data items read in from a back-end data source, And may need to refresh any table records

for items which change, and update the source SQL database when items are added or removed.

Usually, any change in order in a collection is NOT to be reflected back in the SQL data tables, as sorting is

handled in a very different way - so it is adding and deleting which are our real concerns.

PHH - 8th. December 2013.


setting up our collection 'item' class

setting up our collection 'item' class

setting up our collection 'item' class

 Previous topic Next topic

So much of any success we achieve with XAML and data binding, has to do with us defining our

original business or 'custom' class in the correct way.

To be a good citizen of the XAML data binging 'world' our class must implement the most suitable

interface - that of 'INotifyPropertyChanged'. We use an event.

Any data property we create must also fire this event when we change, or set' the property.

When I say 'data properties' think of these as if they are columns from a SQL table.

There may often be others which are require for the internal workings of our business class / object.

Study the following code as a working example of what I am trying to explain :-

=========================================================================================

The above is very much like classes you have already seen, earlier in these eNotes.

Later we will see just what changes we need to make to be able to track via our collection changes,

those properties on the items (in the collection) which are changing.

Most of the class properties are defined similarly to those shown below :-

=================================================================================

The supporting fields are private fields of the class, and the Properties are Public.

You will recognise the Constructors - see below :-

==============================================================================

And the all important method 'NotifyPropertyChanged' is as it always is - and was seen in

previous sections :-

==========================================================================================

And now we need to see how we use our new 'Notify' method.

Below is an example of how it is used in the data properties, when we 'set' or change a property value :-

====================================================================================================

We may have other class properties which we choose NOT to send a change notification.

These tend to be properties used to support the class generally. In the following image we

see an example of this from our 'Vehicle2' definition :-

=================================================================

Lets move on ..............

Now then, after a friendly request from Nick I have taken the STATIC data methods from the Vehicel2 class

definition, and placed them in a separate class.

Here are the methods in question / focus :-

==============================================================================================

And now here we have them in a new class called "MakeMyVehicle2Data" - check this out :-

=====================================================================================================

Out of interest, there is no benefit one way or another, from placing the STATIC methods in a new class.

Just in some way or another Nick must think this is somehow more organised, neat, or tidy. Funny mind

he has !!

Check out the details of the two STATIC methods - see below :-

==========================================================================================

Lets move on and see the Window we need to complete our tests .............

See you in the next section.

PHH - 12th.& 13th. December 2013.


setting up a first test WPF window

setting up a first test WPF window

setting up a first test WPF window

 Previous topic Next topic

When creating a test window we need to try and keep many things as simple as possible.

All we require is enough UI elements to allow us to demonstrate that we are causing changes to

the collection and are handling these changes appropriately.

For our first set of basic tests we are going to use the 'MainWindow' class shown in the following

image of the SE pane - check this out :-

============================================

If we now build and run what I have assembled we see the runtime display see below :-

==================================================================================

Notice in the image above that the main list box is bound to the original collection we will

create using Vehicle2 item objects.

Any changes we make to the collection, as far as member items are concerned, will be done

at a code level - simply because if code changes are handled correctly, then the rest of our

binding will be okay. It is the code changing which is the hardest to get our bindings to show

and reflect in the GUI.

Below, we see that we have a red and a blue button - the click event for these either adds a new

item to the collection ('Add from Code') or causes the first item in the collection to be removed.

Form both of these actions the item in focus is also added to the appropriate 'growing' collection

which is bound to the shorter list boxes.

In the following image the first two collection items have been removed and added to the extreme

right hand list box, as well as one new item being added the the main collection - and the list

bound to the 'Added Items' list box element.

Check out the following details :-

=========================================================================

And allow this is a test app we ought to make sure that if we keep removing items

by clicking the red button, when the list (or collection) is empty we do not get any

exceptions being thrown - this is the test being carried out below :-

=========================================================================

Okay then folks, time that we had a look at the mark-up script.

Below is the script being run at build and compile time, but I have tried to keep it tidy by placing

repetitive script in the Resources section.

First let us study the body of the window script :-

===================================================================================================

As you can see above, it is tidy enough to follow easily.

So now we need to study the Window class properties (attributes) as well as some portions of the partly

collapsed Resources section - check this out :-

=========================================================================================

And now some of the repetitive (or boring) bits :-

========================================================================

Probably the most interesting part of the Resources section is the 'DataTemplate' which is

required to display the collection items in the three list boxes.

In each of the tagged sections for a ListBox we see the attribute for 'ItemTemplate' being

associated as shown below :-

==================================================================================

Lets move on ....................

Setting up the Data Binding :

Because this is just a simple test Window I have not done anything but the basics for binding the

three collections to the UI elements.

First lets see how I have bound the original 'main' collection of Vehicle2 items to the Window and

also the main list box.

Let us first set up the binding to the main 'Window' object itself - check this out :-

======================================================================================

Line 6 seen above is where this is made in the XAML script, and below we see the other part

of the binding specification, that done in the .NET code section :-

========================================================================

This line of code seen at 45 completes the binding of the Vehicle2 collection to the Window.

And because in the following script image, we see line 49 is binding the main list box to an otherwise

unspecified object, it in fact binds to what is bound to the Window - which is the original collections :-

================================================================================

So why do we need to change this arrangement ?

Well, if we did this for the other two list boxes then all three would be bound to the same data object,

which is NOT what we want.

So our simple solution is to name the two right hand list boxes, and bind the growing collections

directly to them as seen in the next couple of images - check these out below :-

=================================================================================

Note that we need to have a name provided for each of these list boxes, so they can be referred to

in the .NET code section (the code behind).

And for 'fun', we can prove that all three list boxes would bind to the original collection if we failed

to add lines 40 & 41 above ........

Check out these results at runtime :-

================================================================================

Yes, as you can see above, we have the same collection showing in all three ListBox controls.

Its even more fun when we try clicking the red button a few times, to remove collection items.

See the following display results :-

=================================================================================

Yes, it is as we said, the second and third collections are not bound, and are therefore not

being shown. However, the unbound collection of Old (or removed) items is still being

populated, we just do not see it.

Lets move on to see and learn ............

Moving towards applying MVVM :

This seems like a good opportunity to use this sample to show what we are doing when we

move towards applying the MVVM pattern.

If we make a 'super class' - and instantiate an object with three properties - each an OC of

Vehicle2 items, we can improve our binding technique.

Checkout this new 'super class' :-

=============================================================================

Okay the guys, the point is that we can now bind an instance of this 'Super Class' to out Window.

The script is still as seen below :-

========================================================================================

The other end (the .NET code end) of the required binding is seen below :-

===========================================================================

So an object with three OC properties is bond to the Window.

However, to bind the separate OCs to the list box UI elements we now need to specify a 'Path' value.

Here in the next three images are the changed 'ItemsSource' bindings.

First the main / original collection binding :-

===============================================================================

And now the new / added collection binding :-

================================================================================

And finally, the old or removed collection binding :-

==================================================================================

Okay then folks - where from here ?

Well, before we move on to see how we handle the tracking of changes, let us make the 'strong' point

that MVVM takes this approach to the limit.

When we apply the MVVM pattern we will make one class of object for binding to our Window.

The Windows will be termed a "View" and the special data class object the "ViewModel".

The VM is bound in one association to the View, and all sub-data objects are properties of the VM.

The data from the back-end data source is an object which is 'projected' (other call it injected) into the

VM as a parameter in the constructor of the VM.

Time to move on .................

PHH - 12th. & 13th. December 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

============================================================================
<Window x:Class="WpfTrakingChanges.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Collection - Changes &amp; Edits :" Height="356" Width="525"
Name="winTraking" Background="Beige"
DataContext="{Binding}">

<Window.Resources>
<DataTemplate x:Key="ourDTvehicle">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Path=Type}" FontStyle="Italic" />
</StackPanel>
</DataTemplate>

<Style TargetType="Label" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Background" Value="Bisque"/>
<Setter Property="Foreground" Value="Maroon"/>
</Style>

<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Width" Value="139" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>

<Style TargetType="ListBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="117" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>

<Style TargetType="RadioButton" >
<Setter Property="HorizontalAlignment" Value="Left" />
<!--<Setter Property="Height" Value="26" />-->
<Setter Property="VerticalAlignment" Value="Top" />
<!--<Setter Property="Width" Value="100" />-->
<Setter Property="Foreground" Value="DarkBlue" />
</Style>
</Window.Resources>

<Grid>
<ListBox Height="185" Margin="10,34,0,0"
Width="139"
ItemsSource="{Binding Path=o3OCV}"
ItemTemplate="{StaticResource ResourceKey=ourDTvehicle}"/>

<Button Name="pbRemoveFirstItem" Content="Remove First Item" Margin="10,7,0,0"
Click="pbRemoveFirstItem_Click" Background="LightCoral"/>

<Button Name="pbAddFromCode" Content="Add from Code" Margin="10,234,0,0"
Click="pbAddFromCode_Click" Background="LightBlue"/>

<ListBox Name="lbxNew" Margin="253,34,0,0"
ItemsSource="{Binding Path=thOCVnew}"
Background="Lavender"
ItemTemplate="{StaticResource ResourceKey=ourDTvehicle}"/>

<ListBox Name="lbxOld" Margin="371,34,0,0"
ItemsSource="{Binding Path=thOCVold}" Background="AliceBlue"
ItemTemplate="{StaticResource ResourceKey=ourDTvehicle}"/>

<Label Content="Added Items :" Margin="253,7,0,0" />

<Label Content="Removed Items :" Margin="371,7,0,0" />

<Button Content="Force a Property Value Change" Margin="10,289,0,0"
Name="pbPropChanged" Click="pbPropChanged_Click"
Width="184" Background="LightGreen"/>

<ListBox Height="106" Margin="253,203,0,0" Width="162" Background="Thistle"
Name="lbxChanged" ItemsSource="{Binding Path=thOCVedit}"
ItemTemplate="{StaticResource ResourceKey=ourDTvehicle}"/>

<Label Content="Changed Items :" Margin="253,177,0,0" Background="Bisque" />

<RadioButton Content="None :" Margin="422,203,0,0"
Name="rbNone" Checked="rbNone_Checked" />

<RadioButton Content="All :" Margin="422,223,0,0"
Name="rbAll" Checked="rbAll_Checked" />

<RadioButton Content="1,3,5 :" Margin="422,243,0,0"
Name="rb135" Checked="rb135_Checked" />

<RadioButton Content="2,4 :" Margin="422,263,0,0"
Name="rb24" Checked="rb24_Checked" />

</Grid>
</Window>
============================================================================
using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//-----------------------------------
using System.Collections.Generic;
using System.Collections.ObjectModel; //----- ObservableCollection -----
using System.Collections.Specialized; //----- NotifyCollectionChangedAction -----

namespace WpfTrakingChanges
{
public partial class MainWindow : Window
{
public FourCollections o4Colls;

public MainWindow()
{
InitializeComponent();
this.Initialize();
}

public void Initialize()
{
this.o4Colls = new FourCollections();
this.winTraking.DataContext = this.o4Colls;
this.o4Colls.o3OCV.CollectionChanged += this.OnVehicleCollectionChanged;

//----- the following is suggested in Google articles -----
foreach (var item in this.o4Colls.o3OCV)
{
item.PropertyChanged += this.OnVehiclePropertyChanged;
//----- also set the 'OurProps' string array property -----
item.OurPropsSel = new string[5] { "VehicleId", "Name", "Type", "NumberOfWheels", "MediumForTransport" };
}
}

public void OnVehiclePropertyChanged(object sender, PropertyChangedEventArgs e)
{
Vehicle2 oV = (Vehicle2)(sender);
if (!this.o4Colls.thOCVedit.Contains(oV))
{
this.o4Colls.thOCVedit.Add(oV);
}
else { MessageBox.Show("Item changed already in 'change set' !","Duplicate :"); }

MessageBox.Show("that prop changed is :- "+e.PropertyName,"Property Firing :");
}
public void OnVehicleCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
Vehicle2 oV = (Vehicle2)(e.NewItems[0]);
this.o4Colls.thOCVnew.Add(oV);
}

if (e.Action == NotifyCollectionChangedAction.Remove)
{
Vehicle2 oV = (Vehicle2)(e.OldItems[0]);
this.o4Colls.thOCVold.Add(oV);
}

if (e.Action == NotifyCollectionChangedAction.Replace)
{ }

if (e.Action == NotifyCollectionChangedAction.Reset)
{ }

if (e.Action == NotifyCollectionChangedAction.Move)
{ }
}

public void pbRemoveFirstItem_Click(object sender, RoutedEventArgs e)
{
if (this.o4Colls.o3OCV.Count > 0)
{
this.o4Colls.o3OCV.RemoveAt(0);
}
}

public void pbAddFromCode_Click(object sender, RoutedEventArgs e)
{
Vehicle2 oV = new Vehicle2(13, "Test Name", "Test Type", 3, "Test Medium");
oV.PropertyChanged += this.OnVehiclePropertyChanged;
this.o4Colls.o3OCV.Add(oV);
}

private void pbPropChanged_Click(object sender, RoutedEventArgs e)
{
if (this.o4Colls.o3OCV[0].OurPropsSel.Contains("Name"))
{
this.o4Colls.o3OCV[0].Name = "Force value change";
return;
}

if (this.o4Colls.o3OCV[0].OurPropsSel.Contains("Type"))
{
this.o4Colls.o3OCV[0].Type = "Force type change";
return;
}
}

private void rbNone_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("rb checked .....","None :");
foreach (var item in this.o4Colls.o3OCV)
{
item.OurPropsSel = new string[5] { "", "", "", "", "" };
item.TrackNone = true;
}
}

private void rbAll_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("rb checked .....", "All :");
foreach (var item in this.o4Colls.o3OCV)
{
item.TrackNone = false;
item.OurPropsSel = new string[5] { "VehicleId", "Name", "Type", "NumberOfWheels", "MediumForTransport" };
}
}

private void rb135_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("rb checked .....", "135 :");
foreach (var item in this.o4Colls.o3OCV)
{
item.TrackNone = false;
item.OurPropsSel = new string[5] { "VehicleId", "", "Type", "", "MediumForTransport" };
}
}

private void rb24_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("rb checked .....", "24 :");
foreach (var item in this.o4Colls.o3OCV)
{
item.TrackNone = false;
item.OurPropsSel = new string[5] { "","Name", "", "NumberOfWheels" , "" };
}
}

}

}
============================================================================
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel; //----- INotifyPropertyChanged -----
using System.Linq;
using System.Runtime.CompilerServices; //----- [CallerMemberName]] -----
using System.Text;
using System.Threading.Tasks;
//-------------------------------------

namespace WpfTrakingChanges
{
class Vehicle : INotifyPropertyChanged
{
//----- fields -----
int _vehicleId;
string _name;
string _type;
int _numberOfWheels;
string _mediumForTransport;

//----- properties -----
public int VehicleId
{
get { return _vehicleId; }
set { _vehicleId = value; NotifyPropertyChanged("VehicleId");}
}

public string Name
{
get { return _name; }
set { _name = value; NotifyPropertyChanged("Name"); }
}

public string Type
{
get { return _type; }
set { _type = value; NotifyPropertyChanged("Type"); }
}

public int NumberOfWheels
{
get { return _numberOfWheels; }
set { _numberOfWheels = value; NotifyPropertyChanged("NumberOfWheels"); }
}

public string MediumForTransport
{
get { return _mediumForTransport; }
set { _mediumForTransport = value; NotifyPropertyChanged("MediumForTransport"); }
}

//----- events -----
public event PropertyChangedEventHandler PropertyChanged;

//----- constructors -----
public Vehicle()
{
this.VehicleId = -1;
this.Name = "...";
this.Type = "...";
this.NumberOfWheels = -1;
this.MediumForTransport = "...";

}

public Vehicle(int nV, string cN, string cT, int nW, string cMT)
{
this.VehicleId = nV;
this.Name = cN;
this.Type = cT;
this.NumberOfWheels = nW;
this.MediumForTransport = cMT;
}

//----- methods -----
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//---------------------------------------------------------------------------
//----- static methods -----
public static List<Vehicle> GetVehiclesList()
{
List<Vehicle> aList = new List<Vehicle>();

Vehicle oVeh = new Vehicle(1,"Racer","Cycle",2,"Road");
aList.Add(oVeh);
aList.Add(new Vehicle(13,"Destroyer","Ship",0,"Sea"));
aList.Add(new Vehicle(3,"Bentley","Motorcar",4,"Road"));
aList.Add(new Vehicle(6,"Tank","Warfare",0,"All Terrain"));
aList.Add(new Vehicle(7,"Bus","Motorcoach",4,"Road"));
aList.Add(new Vehicle(33,"Liner","Ship",0,"Sea"));
aList.Add(new Vehicle(3,"Mountain Bike","Cycle",2,"Off-Road"));
aList.Add(new Vehicle(3,"Dinghy","Boat",0,"Water"));
return aList;
}

public static ObservableCollection<Vehicle> GetVehicleCollection()
{
return new ObservableCollection<Vehicle>(GetVehiclesList());
}
//---------------------------------------------------------------------------------------
}

//===========================================================================================

public class Vehicle2 : INotifyPropertyChanged
{
//----- fields -----
int _vehicleId;
string _name;
string _type;
int _numberOfWheels;
string _mediumForTransport;

Boolean _trackNone = false;
string[] _ourPropsSel = new string[5];
string[] _ourPropsNone = new string[5]{"","","","",""};
string[] _ourPropsAll = new string[5]{"VehicleId","Name","Type","NumberOfWheels","MediumForTransport"};

//----- properties -----
public Boolean TrackNone
{
get { return _trackNone; }
set
{
_trackNone = value;
if (value)
{
this.OurPropsSel = this._ourPropsNone;
};
}
//----- do not trigger a Property Change ! -----
}

public string[] OurPropsSel
{
get { return _ourPropsSel; }
set { _ourPropsSel = value; }
//----- do not trigger a Property Change ! -----
}

public int VehicleId
{
get { return _vehicleId; }
set { SetProperty<int>(ref _vehicleId, value); }
}

public string Name
{
get { return _name; }
set { SetProperty<string>(ref _name, value); }
}

public string Type
{
get { return _type; }
set { SetProperty<string>(ref _type, value); }
}

public int NumberOfWheels
{
get { return _numberOfWheels; }
set { SetProperty<int>(ref _numberOfWheels, value); }
}

public string MediumForTransport
{
get { return _mediumForTransport; }
set { SetProperty<string>(ref _mediumForTransport, value); }
}

//----- events -----
public event PropertyChangedEventHandler PropertyChanged;

//----- constructors -----
public Vehicle2()
{
this.VehicleId = -1;
this.Name = "...";
this.Type = "...";
this.NumberOfWheels = -1;
this.MediumForTransport = "...";
//------------------------------
this.Initialize();
}

public Vehicle2(int nV, string cN, string cT, int nW, string cMT)
{
this.VehicleId = nV;
this.Name = cN;
this.Type = cT;
this.NumberOfWheels = nW;
this.MediumForTransport = cMT;
//------------------------------
this.Initialize();
}

//----- methods -----
public void Initialize()
{
this.OurPropsSel = this._ourPropsAll;
}

protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
//----- from an approach by Charles Petzold -----
//----- Programming Windows 6th. edition -----
if (object.Equals(storage, value))
{
return false;
}
storage = value;
if (!this.TrackNone)
{
if (this.OurPropsSel.Contains(propertyName))
{
NotifyPropertyChanged(propertyName);
}
}
return true;
}

public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//---------------------------------------------------------------------------
}

class MakeMyVehicle2Data
{
//----- static methods -----
public static List<Vehicle2> GetVehicles2List()
{
List<Vehicle2> aList = new List<Vehicle2>();

Vehicle2 oVeh = new Vehicle2(1, "Racer", "Cycle", 2, "Road");
aList.Add(oVeh);
aList.Add(new Vehicle2(13, "Destroyer", "Ship", 0, "Sea"));
aList.Add(new Vehicle2(3, "Bentley", "Motorcar", 4, "Road"));
aList.Add(new Vehicle2(6, "Tank", "Warfare", 0, "All Terrain"));
aList.Add(new Vehicle2(7, "Bus", "Motorcoach", 4, "Road"));
aList.Add(new Vehicle2(33, "Liner", "Ship", 0, "Sea"));
aList.Add(new Vehicle2(3, "Mountain Bike", "Cycle", 2, "Off-Road"));
aList.Add(new Vehicle2(3, "Dinghy", "Boat", 0, "Water"));
return aList;
}

public static ObservableCollection<Vehicle2> GetVehicle2Collection()
{
return new ObservableCollection<Vehicle2>(GetVehicles2List());
}
}

public class FourCollections : INotifyPropertyChanged
{
//----- fields -----
ObservableCollection<Vehicle2> _o3OCV;
ObservableCollection<Vehicle2> _o3OCVnew;
ObservableCollection<Vehicle2> _o3OCVold;
ObservableCollection<Vehicle2> _o3OCVedit;

//----- events -----
public event PropertyChangedEventHandler PropertyChanged;

//----- properties -----
public ObservableCollection<Vehicle2> o3OCV
{
get { return _o3OCV; }
set { _o3OCV = value; NotifyPropertyChanged("o3OCV"); }
}

public ObservableCollection<Vehicle2> thOCVnew
{
get { return _o3OCVnew; }
set { _o3OCVnew = value; NotifyPropertyChanged("thOCVnew"); }
}

public ObservableCollection<Vehicle2> thOCVold
{
get { return _o3OCVold; }
set { _o3OCVold = value; NotifyPropertyChanged("thOCVold"); }
}

public ObservableCollection<Vehicle2> thOCVedit
{
get { return _o3OCVedit; }
set { _o3OCVedit = value; NotifyPropertyChanged("thOCVedit"); }
}

//----- constructors -----
public FourCollections()
{
this.thOCVnew = new ObservableCollection<Vehicle2>();
this.thOCVold = new ObservableCollection<Vehicle2>();
this.thOCVedit = new ObservableCollection<Vehicle2>();
this.o3OCV = MakeMyVehicle2Data.GetVehicle2Collection();
}

//----- methods -----
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//-----------------------------------------------------------------------
}

}

//-------------------------------------------------------------------------
============================================================================

============================================================================
PHH - 13th. December 2013.


Tracking item changes in 'ObservableCollections'

Tracking item changes in 'ObservableCollections'

Tracking item changes in 'ObservableCollections'

 Previous topic Next topic

Let us make it VERY clear just what we mean by this 'sub-section title'.

We say a 'collection' changes when it has items added to it, or removed from it.

We also say that the collection changes when the entire list is refreshed.

As developers of 'Business Solutions' we are usually just interested in 'Add and Remove' -

new ones added and old ones removed.

The 'Collection' is not seen to have changed if a property of an existing collection item has

a change in value. If a Customer ID values changes from 13 to 31, is not generally seen as a collection

change.

Item property value edits are handled (dealt with) in the next sub-section - we can log property changes

if we so wish - as long as we know how.

The OC (ObservableCollection) class implements the interface called 'INotifyCollectionChanged', and

it is with this that we track the changes of 'Add & Remove'.

This 'stuff' is much easier to see and understand, than it is to be written about and read.

Making a Start - creating a Suitable Example :

Okay then folks, we have seen how to make a suitable Window to display our UI elements stuff, now we need

a code behind section to accompany it.

Check out the code below to see the three OCs which we create and bind to the GUI controls :-

===============================================================================================================

In this very simple code binding we see that lines 39, 40 & 44 do the job nicely enough.

Notice in the code above that line 46 is VERY important as it uses a delegate to associate the CollectionChanged

event firing with the handler method being actioned. The handler method is "OnVehicleCollectionChanged" and it

is ours - we both name it, and design it.

*** Remember *** a delegate is like an 'action pointer' - it 'points' the event at a method to run, or action, when

the event triggers (or fires).

Here in detail is the binding of the main collection to the window itself :-

===============================================================================

And here below is the delegate being set :-

=========================================================================================

Since we are just exploring the possibilities of collection item tracking, we do not need much of a

clever handler code section - this will do nicely :-

=======================================================================================================

So you see in the above code that we are just tracking items added or removed, and adding the

particular item to the appropriate growing OC - one bound to the second or third list box.

Now we need to examine in detail what the button click events on the two buttons do for us.

Here is the first one, the one which does 'Remove' :-

===================================================================================

*** NOTE *** above that we are not coding the item to be added to the growing OC, we will

let out 'handler' do that for us.

Now check out the code for the click event handler on the 'Add' button :-

============================================================================================

Once again, the above code does NOT actually add the item in focus to the growing list - one again

that is left to the 'Change' delegate and handler.

Lines 79 and 97 above, deal with the addition of the in-focus item to the appropriate growing OC for

add or remove.

Note that it usually is the code changing of collection, and item property, which is the hardest to

get out UI to respond to, not the UI element binding.

Get this code change working right and most other things will be okay.

Time to move on .................

See you in the sub-section which tracks the property changes on the collection items.

PHH - 8th. * 13th. December 2013.


Tracking property edits in collection items

Tracking property edits in collection items

Tracking property edits in collection items

 Previous topic Next topic

You may have realised by now that in order to track changes, we need an appropriate event to fire, and

then a delegate to associate the event triggering with a method handler which will be run.

Previously, we used the 'CollectionChanged' event on the OC itself.

Now we need to find and associate the 'PropertyChanged' event on the items themselves with a delegate

and method 'handler'.

Before we see how to set the delegate correctly, let us see the display at runtime for testing and trialling.

Study the extra UI elements - mainly those to the right of screen, but also the green button :-

================================================================================

The extra UI elements help us see what is going on when we force a code change on one or another

of the property values on the collection item which is first in the list / collection.

There are five properties, and we have four radio buttons to represent most of the various combinations

of these properties.

It is the clicking of the green button which the does the code 'forcing' with the set/selected choice.

Check these screen details :-

=============================================

And to prove that some of this works, check out the following image where we see

details of forced value changes on both 'Name' and 'Type' properties.

[ .. Property 2 is 'Name' and 3 is 'Type' ..... ]

=================================================================================

Take it from me that when 'None' is selected nothing appears to happen (at all) at the

GUI surface.

So how do we make this work for us ? :

Let us start with the radio button selection.

In the following image we will see details of the just two of these radio button code handlers.

They are handler methods since the are fired by an event, the 'Checked' event on the 'RadioButton' object.

Study this carefully :-

===============================================================================================================

As you can see above the code sets a five item string array with appropriate string values.

Let us now check the extra script in our mark-up, see lines 80 - 90 where we have four events associated

with a handler in code :-

=================================================================================================

We will come back to the ListBox shortly, for now lets see what the green button click event handler

code does for us - check this out :-

=================================================================================

Yes, quite simply we check to see if 'Name' or 'Type' is in the short (5 item) string array. If it is we

cause the appropriate action to be taken.

As I said earlier - this is not a very clever or ambitious action, just enough to see that things are working.

Now then, we are getting towards the cleverer parts of this tracking - before we deal with the 'main' part

let us see what our delegate 'pointer' has the app do when the handler method is fired for 'property change'

on the item properties - check this out :-

=======================================================================================================

Okay then, that makes sense - ONLY if the item is not already in the growing list do we add it to the list,

or collection.

Finally, the crucial and IMPORTANT bit - how to set the delegates.

Each item (object) in the collection needs to have its event for 'PropertyChanged' associated with a delegate

which 'points' to a handler method.

For us the handler method will be the same for each item - we have named it 'OnVehiclePropertyChanged'.

*** Note *** in other circumstance we could use more than one handler depending on the item in some way !!

Lines 52 to 61 in the following image show how we cycle though the collection and make the delegate association.

Study this carefully :-

================================================================================================================================

You will notice that on line 61 we are also setting the short array on the Item to be 'ALL' properties.

Having set the delegates correctly, how do we handle the fact that we wish to be able to select which

properties we track.

Choosing which Properties to Track :

We know that we use, in some way, a short (5) string array of property names, but how does this work ?

Let us now look at some new code in our 'Vehicle' class - this has now become 'Vehicl2'.

===========================================================================================================================

It will become apparent soon, why we need to have a helper property called 'TrackNone', to make things more

efficient, but for now lets see some more of the basic added code lines.

Here is the new string array property - which uses a private field :-

======================================================================

Notice that we don't send notification for this property, as its not a data property, but a support or

helper property.

Now then, when we see a standard data property we also notice that the way we 'set' it has changed from

in the Vehicle class.

I am using some code I saw in Charles Petzold's book on Windows Programming 6th. Edition.

Study in particular line 156 :-

========================================================================

To initialise the the object at the time of Instantiation, we set the selected properties array to be that of

the 'All' properties array :-

==========================================================

And finally, the part we need to think about VERY carefully, I suspect.

Here is one method from Charles's text which allows us to do a few things at once - we can set a property by

specifying what is returned, BUT, also check to see if we

====================================================================================================================

*** note *** I am not quite sure about the pair of returns for 'true' we may be able to reduce these.

The following 'improved' code seems to work, but may need further testing - check this :-

===================================================================

Okay then guys, things seem to track the property changes a-okay, so we can move on .......

See you in the next section.

PHH - 12th. & 13th. December 2013.


Getting XAML ready for 'Data Binding'

Getting XAML ready for 'Data Binding'

Getting XAML ready for 'Data Binding'

 Previous topic Next topic

There are many,many, ways of creating our XAML so that data binding of some description

would be possible.

This is why we need to look ahead to the way the creators of the MVVM 'pattern' have gone

about setting up XAML elements and binding to their attributes / properties.

When we take the lead from the MVVM (very experienced) guys we find out that there is a way

to prepare our XAML, as well as the .NET code, which is sensible and can be made to be consistent.

Even though we are not going to always apply the full MVVM 'pattern' we can still keep to the same

way of preparing our XAML script.

1. Firstly, we are NOT going to place ANY custom data values, or any form of business logic, into the XAML script.

2. We will attempt to keep clear of using Events, by using binding to suitably provided attributes / properties.

3. Where possible we will provide 'DataTemplates' for collection items, and use binding within these.

4. Any binding to the WPF / WinRT / Phone 8 'Form' will be done by one line of binding.

5. A 'Super Object' class will need to be designed and created which can be bound in this one line binding.

6. In the XAML script, binding is made to the public properties on this 'Super Object' (SO).

7. Refrain from naming the UI elements, unless required by 'intra binding' of one UI element attribute to another.

8. Design your SO first, and then the UI layout to display all of the SO that is required to be shown.

PHH - 11th. March 2014.


what is required in the XAML file

what is required in the XAML file

what is required in the XAML file

 Previous topic Next topic

Use the provided DPs - properties related to events - like the 'SelectedItem' in a list control.

Bind this to a suitable property on the SO (Super Object) - then the operation of the control will

automatically fill, or populate, the property with a value.

If this property is then bound to another display element, like a TextBlock, then the change in

selection will show immediately.

PHH - 11th. March 2014.


what is required in the .NET code file

what is required in the .NET code file

what is required in the .NET code file

 Previous topic Next topic

If we have designed our 'Super Object' and then the GUI surface correctly, we will not have need

to use names of specific UI elements in our .NET code.

1. Firstly, the .NET 'code behind', which goes hand in glove with the XAML file, should be virtually empty.

That means it just has the code 'stub' that the template provides and nothing of our doing.

2. Any .NET code we have to write in order to support the data binding to the UI 'Form' - we often call

this the 'View' - should be done mainly in the ViewModel file.

3. The 'Model' file is also .NET coded, and is designed to provide the ViewModel constructor with a

parameter object from which all (or most) of the VM public properties can be assigned. Basically,

ViewModel properties point to the originating Model property values.

4. If we are not applying proper MVVM by using a provided framework, then we may have to use the

odd Event or two, but most can be avoided. Commands for many UI controls can only be made and used

if an MVVM framework is being used.

Keeping the Code Behind 'Clean and Clear' :

Whether we are using VN or C# the .NET code should look similar to that shown below :-

===========================================================

PHH - 11th. March 2014.


what is required in the DataTemplate

what is required in the DataTemplate

what is required in the DataTemplate

 Previous topic Next topic

===========================================================================================================

PHH - 11th. March 2014.


'Data Binding'

'Data Binding'

'Data Binding'

 Previous topic Next topic

What is 'Data Binding' ? :

UI elements (or controls) have many properties (attributes) which need values to be assigned.

Some properties have values assigned which are most likely to relate to what we would call 'data'.

Values can be hard-coded into the properties/attributes - this is NOT 'binding'.

Below is an example of 'hard-scripting' - check line 254 :-

====================================================================================================

[ .. the result is shown at design time, on the graphical designer surface .. ]

However, in place of a value, these properties/attributes can be given a 'pointer' which points to where the

value can be found in memory.

The 'pointer' aspect of this is hidden, and we talk in terms of 'data binding' instead.

Below is a similar UI element, but with a 'binding' syntax - check this out :-

==========================================================

In the above image line 261 is the 'effective pointer' to where a value may be located.

There is a property called 'AllDetails' which is filled at run time - this is 'bound' to the Text attribute of the 'TextBlock'

control.

When we 'bind', we often get an obvious change on the designer graphical surface - see below :

================================================================================================

Although the designer is quite smart, and does most things in real time, as we design, it can't display

a value which is only determined at runtime.

Here are some details of the 'AllDetails' property of the Friend class :-

==================================================================================================================

And here is how the start/top of the Friend class looks when collapsed :-

=======================================================================

So we need to bind our TextBlock 'Text' property to the 'AllDetails' property on the Friend object.

When we use the Friend class in the main body of our screen class we do this - check below :-

=====================================================================

So the Friend object is bond to the screen object.

The value of the 'AllDetails' property is resolved at runtime, and then displayed.

One to Many :

Okay guys, we can bind 'one-to-one' as seen above, or we can in fact bind 'one to many' where

the one is the source and the many the target.

Checkout the following images and details :-

===============================================

We have (above and below) three similar TextBlock elements, and they are each bound to the

same original .NET code property called 'AllDetails'.

[ .. the 'Name' attribute does not need to be specified as it is not used.. ]

=====================================================================

And as we should expect, the designer does not show any text values as these are

only resolved at app runtime.

Check out the graphical designer, see below :-

==============================================

Lets move on to another interesting situation ......................

Making 'Chains' :

Often properties can be bound to other properties, whether the originator has a value or yet another binding (or pointer).

Yes, bindings can be chained. Obviously, at the end of a single or chained binding, there must be a value.

So the general process of 'binding' means that data values are NOT held in UI element properties, but elsewhere,

and usually in a separate data object.

===========================================

=================================================================================

=======================================================================

============================================

Why do 'Data Binding' ? :

It is usually seen as the code / script 'association' of objects and properties with GUI elements on screen.

When values are changed either on screen or in code (behind) the UI display shows the changes is all parts

which are related with the values that have changed.

Data Binding has been around for a long time, but many developers have not used it to any serious level.

With XAML technology, coupled with WPF, we see a very good support for Data Binding, and one we all

need to use to make our lives easier and better, as well as making our applications modern and suitably functional.

If we are to tap into any parts of the MVVM pattern, using some of the freely available frameworks, then we must

embrace Data Binding in all its power and glory !

'Data Binding' is one of the best things that ever happened to me in my coding career ;-0)

I suggest you also embrace it, as it is as applicable to WPF as it is to WinRT (Tablet) and Windows Phone 8 as well.

All we need to get into Data Binding is a few well written and clear examples to follow. Copy and adapt, that is the way

forward.

If you read and follow through these eNotes, you will be guaranteed to have some success.

Find the walk-through sections to see have this can be done from scratch - with a new and blank app - using VS 2012

as well as possibly VS 2013.

Any guy serious about XAML and data Binding will also need to be able to code in C# as well as Vulcan.NET. And with

Redgate's Reflector 8 available there is no excuse for not mixing the two.

*** See the section on Reflector 8 later in these eNotes ***

Going Forward - MVVM :

Once we get familiar with using Data Binding, then it is only a couple of more steps to applying the MVVM 'pattern' of

application development.

To move towards MVVM we need to stop adding code to the 'code behind' (CB) file supporting the XAML window / page.

In order to not place code in the CB we will have to handle 'Events' differently - we use Commands instead.

I thoroughly recommend using MVVM, and MVVMLight (MVL) is an easy way in to it, and can be used on all platforms,

WPF, Tablet and Smartphone.

PHH - 18th. October 2013 & 5th. January 2014.


Simple example - 'Binding', doing it right

Simple example - 'Binding', doing it right

Simple example - 'Binding', doing it right

 Previous topic Next topic

In this simple example we are going to 'hold' all data in the .NET code driven objects, and

none in the actual properties/attributes of the UI elements themselves.

Let us take a look at own trial screen, just after app launch - see below :-

========================================================

Okay then guys, nothing special, in fact it look rather boring ;-0((

What do we have ?

We have a string property on a .NET coded object, called 'Message'.

This property is bound to the Text attribute (property) on each of the three TextBlock UI elements, as

well as the Text attribute on the 'TextBox' element.

Because the TextBox is set to be R/W we can change the string text. Check out the results below :-

[ .. TextBlock elements are R/O and to display string data .. ]

========================================================

When the above image was generated, I needed to enter the whole new text string and then move focus

by pressing the 'Tab' key.

Here is how the XAML script looked for this situation :-

==========================================================================

Note line 274 in the above image - this is what delays the on-screen changes to be a loss

of focus - from the TextBox to another UI element.

Here below you can see this behaviour - where changes show in the TextBox but not any of

the TextBlock elements :-

=======================================================

*** Note *** The default behaviour is 'lost focus' as explicitly shown below :-

======================================================================================

Now then, if we change this as shown below, we get quite a different behaviour - check this out :-

===========================================================================================

Now we have set the updating trigger (above) to be one of a property changed notification type.

By changing to this setting we see changes as they occur, character by character, and not just

when the focus changes to another UI element.

Here is this behaviour at runtime - check it out :-

========================================================

Above we are part way through entering "now set at Property Changed".

Lets move on .....................

What do we need do in our code to make this happen ?

Well, we need to specify an initial string value for 'Message' - see blow :-

=========================================================

We also (see above) need to bind the object with the 'Message' property to the GUI screen

object.

Unfortunately, when we try to do things simply, it can look a bit confusing - almost as it we are

joining an object to itself - but we aren't.

The 'DataContext' property is just being associated with the bunch of properties of the main class.

In the XAML script we need to do the following (ONLY) - check this out :-

=========================================================================

Often when we start data binding we are so desperate to get it to work that we include extra and unnecessary

code and script lines.

There is NO need to do the following - lines 8 & 9 are superfluous :-

=================================================================

It always seems a good idea after getting DB to work, to try commenting some of the code/script lines to

see just what is really needed - I did this for the example above.

Moving on ................

Remember that we said the MOST important thing for success was to get the properties for binding

set-up correctly for sending out system messages when the properties change.

Here is the necessary code which makes 'Message' work as well and correctly as it does - check

out all of the details below :-

=====================================================================================

Okay then folks, this is fine.

Lets try and make our sample a little more interesting ;-0)

Taking things further :

We are going to see just how we can have one source property, edit this in the TextBox element,

and then display three related (but individually separate) properties in our three TextBlock elements.

Take a look at our working form of this new sample :-

========================================================

Before we move into the details of our new sample, first lets see what the interface implementation

code does for us.

Notice that on line 20 in the above code image, the " implements INotifyPropertyChanged " is VERY necessary to

make our code work correctly.

If you don't believe me, or you need proof, then try commenting it and rebuilding and running the app.

Here is what I get - check thoroughly, and think :-

=========================================================================

I think you will find that is has to do with registering the class (in this case 'Window1') with the system

which handles all the notifications for changing of properties - if its not registered then we get no

messages flowing back and forth, which are related to properties and their changes.

Let's move on ....................

The New and Extra properties :

In order to complete the bindings for the three 'TextBlock' elements we need to have three new properties.

These 3 are similar to the 'Message' property, with a slight difference - they are calculated properties.

Let us look at the new code lines, and then we can walk through them later, one bit at a time.

Check this out :-

==================================================================================

In the above code image look at lines 40 through 48.

We actually have three properties similar to this new one - lets call them A.B & C.

Each time one of these three properties is read (or used) it has a calculated output - see line 42.

On the other hand, when the 'Message' property changes, line 37 forces a re-calculation of the values

for the 3 new properties.

You may need to take some time over thinking about this, and getting your head around it.

Changes to our XAML script :

Since we now have four separate properties bound to UI elements then we have had to make changes

to the XAML script to make these new binding work correctly for us.

Check out the following details :-

===========================================================================================

In the above image we see lines 263, 267, and 271 with new bindings.

The line 274 is as it was previously, it is only the TextBlock bindings and properties bound, which

have changed in our upgrading of the sample.

Oh! - lets remember to see the videos of the apps running ..............

ABC text display

=========================================================

Focus change ...

Property change ...

===========================================================================================================================

Okay the guys, time to move on.

Lets go to the next sub-section to learn and see some more binding 'stuff'.

See you there .................

PHH - 6th. January 2014.


Simple Example 2 - 'Width' and 'Height'

Simple Example 2 - 'Width' and 'Height'

Simple Example 2 - 'Width' and 'Height'

 Previous topic Next topic

As you will find out in later sub-sections of this section on 'Data Binding', there are many UI

element properties which can be used for binding - some of which we may not regularly use

in our business solution apps.

So in this sub-section I will explore with you a couple I have not previous used or tried.

It would appear that all UI elements inherit from the class entitled 'FrameworkElement'.

I have just there used VS Help Viewer 2.0 to check a good handful of controls we commonly

use and all have an entry similar to that shown in the following image - check this out :-

========================================================================

If we locate this class in the SDK docs then locate the 'Fields' section, we see the detail shown

in the next two images - check out these :-

[ .. the first image is to show the 'Fields' heading .. ]

=================================================================================================

And now the two fields / dependency properties :-

=================================================================================================

=================================================================================================

We will see how to use the SDK docs more fully and a later subsection.

For now, we just need to know that Width and Height are properties that will bind to suitable .NET code

properties that we define in our custom / business objects.

For our sample testing we will use the 'TextBlock' control (or UI element).

When we drag and drop such an element onto our Widow design surface we see this shown below :-

=========================

And this is accompanied by an insertion of the following XAML script within the editor - check this :-

[ .. ever so slightly edited - from one to two lines created .. ]

=============================================================================================

No sign in mine of any Width or Height attributes, so lets manually add them - check below :-

===================================================================================

And the graphical display changes a little - as seen in the next image :-

=======================

Lets move on, we need to have a class suitable for binding to the 'TextBlock'. Lets make one ....

The 'HeightWidth' class - definition :

To help us get our binding right, we need a suitable class, one with both a height and a width related property.

We will be best to keep to our recommended way of creating a binding class, i.e. making sure that we track

changes to the class properties - check out these details below :-

====================================================================================

So the above code is just as we might expect for our new small class.

Let us see how we can use this in our main window class - check below :-

====================================================================================

Yes, we need to add an extra property into our main class - as seen above.

We will also need to add a new section for the Property code - as seen below :-

=========================================================

Once again, this is all to be expected, to fit into the general pattern of DB class structure.

Now we need to see how our XAML script has been adjusted to suit our new class.

Check out the last five lines of the following script :-

======================================================================================

And now we need how to initiate this in our .NET code - check below :-

=====================================================================

In the above image we see an object of the new class being instantiated, and then associated

with the 'DataContext' property / attribute of the 'TextBlock' UI element.

Here is an indication of the resultant display :-

=============================================================

Before we move on to add the final polished parts, lets move the TB element to make room for

some suitable expansion in both directions - check below :-

=============================

The above will do, and the new back colour will help us see what is going on as well.

Lets make some final adjustments to our 'HeightWidth' class ............

Going a Step Further :

Okay then guys, let us take that step or two further in our data binding exploration.

Check out the following initialising .NET code with the resultant screen display :-

======================================================================================================

We now are using a third property, a string property, and one we will use for text information displaying.

Here is the way we do the extra binding :-

=====================================================================

And here is the extra code we have needed to add to the code class :-

==============================================================

Fine - we should understand what we have done above.

Now lets make a final step or two .............

Sliders to Change Values :

Let us now add a slider or two to see if we can complete our binding exercise in style ;-0)

We are to try and bind the Width attribute so that moving a slider will change the screen display

accordingly.

The slider value property will be bound to our in-memory .NET code object public property. The correct

way, as will be required when we get 'separation' and do things the MVVM way.

Here is the Slider object in mark-up script :-

============================================================================

And now we can view the code association between the XAML element object and the .NET code

object - check the following image :-

==========================================================================================

Well then, the above new code and script works well and we get a working slider which changes the

width of the TextBlock on screen.

I will now add another slider so that we can control the Height attribute/property as well.

We can now use this double slider version of our app to check for touch screen functionality.

Touch and Sliding :

Since I have a main monitor on my desktop system which is a Touch Sensitive one, we can see that

everything we have done is operable by finger touch.

The following image is of me dragging the horizontal slider with a touch stylus - it is easier than my finger

with this desktop app. - note below the little diamond shaped icon / symbol near the 'thumb' of the

horizontal slider :-

==============================

Take it from me that both slider function with the stylus.

I have made a video showing this and it is embedded into the Power Point presentation for Cologne.

Okay folks, lets now move on to check that we have full and responsive 'binding' ...........

Forced Value Changes - from .NET Code :

As you may know by now, the best way to test to see whether you have gotten your classes right,

and that data binding is fully operational, is to some how force a .NET code change of the property

values.

Below I show a screen where we have a push Button which has a Click event linked to an event handler

which causes such a code change.

Here is our new look app :-

=================================================================

When we click the Button at the top, the three values of the 'HeightWidth' class are changed in code.

Both the slider 'Thumb' positions, and the text information too, should change at a mouse click.

Oh! and 'Yes' - at the touch of a finger too ;-0)

For your information, here is the script for the Button :-

============================================================================

The event and handling is done the conventional way - before we move to MVVM !

The handler method is really pretty simple to follow - check this :-

===================================================================================

Now go and find the PP slides and look at the videos of this in real time.

Oh! - first for everything, I see we can do this inside the HnM6 and CHM file - fingers crossed,

give these a go :-

========================================

Time to move on. See you in the next section ............

PHH - 7th. January 2014.


Binding - using one object or many !?

Binding - using one object or many !?

 Previous topic Next topic

Binding - using one object or many !?

 Previous topic Next topic

This small sub-section is really a stepping stone to MVVM.

However, even if you do not go any further toward MVVM, using one object to bind to a whole

Window, or Form, is indeed good practise.

For a screen or form, think of objects like Window, Page, UserControl, when coding in WPF and mobile

technologies - and Silverlight.

If we have one 'super' object, which we bind to a Form/Window, then we say we have 'loose coupling'.

Or at least we are a good way towards 'loose coupling'.

"Loose coupling" is something talked of often with the MVVM pattern. In my opinion it is a good idea ;-0)

A Good (and simple) Example :

With all these sorts of things, it is best to have a clear example to follow.

Let us study the following image - see below :-

======================================================================================

In the above image we see three list boxes, each of which is bound to a collection.

However, the three collections are not 'separate' objects, but instead properties of one larger,

of a 'super' object.

This 'super' object is what is bound to the Window itself.

If we look at the header for this Window we see that we have set the Window up for 'binding'.

Check this out, and particularly line 5 - see below :-

=====================================================================================================

We actually need both script and code to complete a 'binding' or "loose coupling".

Here below is the .NET code required - line 46 does the binding part :-

================================================================

In the above image of .NET code we see that line 46 is binding the single object of type 'MixedGuys3'.

We now need to see just what this class looks like at the moment - before we add any further properties.

Check this out carefully / thoroughly :-

==========================================================================================

You can see above that the current 'MixedGuys3' class has three collection properties.

Lines 92 through 94 show these three properties, each of which is a List<T> of Person objects.

The above class of object is very similar to that which we have seem previously for property

'binding', it just does not have the INotifyPropertyChanged interface. This is done for a purpose,

as we will handle changes in the collections another way - using the 'ObservableCollection' type.

If we are to add some single data value types as extra 'Properties', then we may well need to add

the interface to handle the value change notifications.

Moving on - Setting the collections :

With our simple multi-collection class called 'MixedGuys3', let us see how we can best set the

collections from our initial calling code.

The following image shows how we can supply three collections from static methods.

Checkout the following details :-

============================================================================================

The code for the three static 'collection' methods is straightforward, and is show below :-

=============================================================================================================

We obviously need a constructor set up to accept such three collections, and this is seen in

the next image - shown below :-

==========================================================================================

Lets move on ................

More of the 'Binding' :

Okay then guys, so far we have seen how the 'loose coupling' has bound our multiple object to the

Window / Form, but now we need to see how the individual collection 'properties' are bound to the GUI

elements themselves.

Study these details :-

===================================================================================================

Note that we have bound the ListBox to the 'BadList' property of the 'Window bound' object.

In our example the collection property called 'BadList' is bound to the ListBox UI element (control) called

'lbxBad'.

To save extra scripting we have defined and employed a 'template' in our Resources section.

This same template is used for all three ListBoxes and looks like the following :-

===================================================================================

This means that all the visible contents of each of the three ListBox elements are 'Person' property values

from within the separate 'Person' objects of the collections.

Here is the full script section as it has been used :-

[ .. notice line 76 where we have an alternative syntax .. ]

===================================================================================================

Lets move on a pace ..............

Taking things further :

At this current moment the Label headers are hard scripted - into the XAML script in our editor. And the results show

as seen below :-

=====================================================================

A section of XAML script looks like this - for the 'Good' guys :-

============================================================================================

Now then, how do we improve this ?

So what if we wish to have these label headers bound to property values too ? That is not difficult to do.

Well first of all, lets see the new XAML script :-

=======================================================================================

Note that in the above code we have binding now set, and that we can see a possible variation in the syntax

used to set the 'Path' attribute.

One option (as shown in line 86) is to drop the 'Path=' and just specify the property name.

Let us now see what we have to do to change our 'MixedGuys3' class to have label headers.

Check this out thoroughly :-

==================================================================================================

Yes, above we have added three string properties, and then set their values in the 'Initialise' method.

Lets run this new version of our code / script - see below for the results :-

=======================================================================================

So far so good ;-0)

We are making progress, steadily but surely !

Let us now move to the next sub-section to see what else we can learn about binding ..............

See you there.

PHH - 21st. October 2013. & January 6th. 2014


Binding your data to the GUI Window / Form

Binding your data to the GUI Window / Form

Binding your data to the GUI Window / Form

 Previous topic Next topic

Probably the biggest problem for new guys coming to XAML and 'Data Binding' is that there

are so many ways of doing things - all which appear to work.

What has taken me a LONG time, and MUCH effort, to find out is one way of doing things for

all screens I design and create.

We need to have one simple but effective way of binding a single object to a single form/screen.

If we learn how to do this so it works for any complex object, with any number of complex properties,

then we can do the same for all of our forms/screens.

Getting away from the 'Mess' :

It is possible to bind many separate data objects to a host of UI elements - this is what can happen when

the developer does not plan ahead, and take the time to create a 'Super' data object.

If we are using the MVVM 'pattern' of development then this 'Super' object is called the 'VM' or ViewModel.

Please note however, that this is still a good and organised approach, even if we are not applying full MVVM.

I try to do this all of the time now, even if my app is not based on 'MVL' or 'Prism'.

Lets move on a pace or two ............

We need to see 'Mess' so that it can be Avoided :

Okay then folks - when I say 'mess' I will still make a clean and tidy job of the script and code. The

messy part will be to do with all the separate bindings associations.

In the image shown below we see eight UI list elements, each of which has a separate binding made

in the code section.

Check this out before we examine the details of our new Window in WPF :-

=================================================================================

Okay then, our new Window is called 'Window2' - default from VS2012.

Checkout below the eight list controls, their attributes have been cleaned by the implicit use of

Styles in the Window 'Resources' section :-

===============================================================================================

In the above image, note in particular the 'Name' and 'ItemsSource' attribute specifications.

Now we need to view the .NET code side of the binding associations - see lines 26 through 34 :-

========================================================================

The only reason the above example is not more 'messy' as far as the bindings are concerned, is because

I could not be bothered to do any more work and typing.

Eight instead of one, that is enough extra bindings to help make my point.

Lets move on ......................

How does the 'Mess' come about ? :

Mainly this occurs because we see simple examples in books and articles, and then apply what we have seen.

Because it appears to function we are happy, and move on.

So I would say the 'Mess' happens because we are not thinking widely enough, or even 'out of the box'.

Just because we can bind a simple object directly to a UI element (well one of its properties) does not say we

ought to, or that it is good coding practise.

I used to make a 'mess' because I was struggling with Data Binding in general - I was looking for 'the light' !

What I now see/read is that so many potentially good books on XAML start us off at the bottom, that is they

start us on small and simple examples, and try to work upwards - from bottom to top !

Many of us developer guys know that 'Top Down' design is good, and that often 'Bottom Up' leads to us

falling into traps, and confusing any design ideas we may have thought of previously.

So for me, to get away from the 'Mess', we need to see how MVVM would go about it - then all things

simply fall into place. So MVVM can be thought of in many ways, as the 'Top Down' view of things.

I wish I had come to this 'Top Down' XAML / WPF approach earlier - life would have been a lot easier. But

now I know, I will stick with it.

Move on to the next sub-section to see how you may avoid the 'Mess' !

PHH - 6th. January 2014.


Binding - Avoiding the 'Mess' - an example

Binding - Avoiding the 'Mess' - an example

Binding - Avoiding the 'Mess' - an example

 Previous topic Next topic

Avoiding the 'Mess' - an example and some tips :

PHH - 10th. January 2014.


Binding - how GUI and code interact, or NOT

Binding - how GUI and code interact, or NOT

Binding - how GUI and code interact, or NOT

 Previous topic Next topic

This is a small topic section BUT a very important one.

The whole point of an MVVM approach is that the GUI script and the ViewModel code be

quite separate from one another.

The VM code should not know about the existence of a 'View' object above it, and this means we

should not 'Name' UI elements and then use the 'Names' in the .NET code of the VM class / object.

Unfortunately, there is much material out there which happily mixes up code and script.

Even if we are not apply all (or any) of the MVVM 'pattern' we can do well to try and keep our GUI

script clean and clear of the code behind, and also make our code behind as clean as possible from

referring up to the 'View' or UI screen.

If you are like me you may have started to learn from published simple examples, where it seems

smart to be able to create .NET objects from the XAML script side of things, and much more stuff

that today makes no sense at all.

Just because something can be done, and in the short term works, or functions, does NOT say that

we should be designing our apps that way.

It took me a long time to realise this, and now I have heard of "separation" things all seem to fit into

place.

Telling oneself that all data is to reside in the code behind, or the ViewModel object code, removes

the need to know how to do many clever script / code tricks.

When we apply the MVVM 'pattern' correctly, we don't actually have data values residing in the VM

properties either. We instantiate a VM object by supplying the constructor with an object parameter,

or a few of these.

The object(s) we provide is called a 'Model' object and the process is called 'injection' although I think it

ought to be called 'projection'.

We then 'effectively' set-up the VM data properties with pointers to properties (with values) in the 'Model'.

So it this case the GUI to code binding is really binding a property on a UI element with a value property

in the 'Model'. Only a few data properties will start in the VM, and most of these will be for operational

functionality.

Realising that property - property binding is the key to everything, also helps a lot.

PHH - 8th. January 2014..


What UI element properties can be bound ?

What UI element properties can be bound ?

 Previous topic Next topic

What UI element properties can be bound ?

 Previous topic Next topic

This is a simple enough question, with a more than LARGE answer !

However, the idea is quite easy to understand.

There are many UI elements in the WPF toolbox, and most of these have a large number of

properties defined in their respective classes.

Also there are many properties on the classes from which the UI controls and elements inherit.

All of what we need to know is in the SDK docs provided in Visual Studio 'Help Viewer 2.0' (HV2).

We do need to know just how best to use the documentation however, and what to look for, and

also where to search.

First things First :

We are going to be looking for DPs (dependency properties) and these are indicated in the 'Fields'

section of each XAML/WPF element class.

We will first focus on the 'TextBox' control. This is a UI element, and inherits from 'FrameworkElement'.

Search the HV2 information using 'textbox class wpf' and click / highlight the .NET 4.5 version - here is

some of what I then selected from the large amount of information :-

===============================================================

Ignoring the sections for Methods, Events and Properties for the moment, we see the all important

section on Fields - check below :-

=============================================================================

The second column is what we need to read, the blue lettered words are the names of the Properties

we can use for binding - they identify DPs (dependency properties).

Okay, "that's all very well" I hear you say, "but where is the 'Width' property ?".

Arrrh !! There lies the problem, the above Fields list is only part of what we need to know ;-0((

Let us now look in the same class SDK docs 'Tab' for the Property called 'Width'.

Check out the result of the search / find below :-

=======================================================================================================

The above detail suggests that Width is based in the 'FrameworkElement' (FE) class, from which TextBox

inherits.

Lets have a look at the FE class and its available 'Fields' - check out this below :-

=======================================================================================

======================================================================================

======================================================================================

Yes, as you can see above, we have both Height and Width properties indicated in the Fields

section of the 'FE' class.

So one answer to the question of which properties ? is that the list is tree structured, and the

individual properties come in groups, determined by the tree nodes of the class inheritance.

This would then shine VERY bright light on the fact that the Fields list for 'ListBox' is as

short as the following image suggests - check this out :-

==========================================================================

The 'ListBox' class has a huge number of events, methods and properties, and yet only two Fields,

indicating those DPs for binding use.

The Inheritance Hierarchy 'diagram' helps explain why :-

==================================================

Obviously, only two more Fields were added in the 'Controls.ListBox' subsection.

We already know that the 'FE' subsection contains Height and Width.

Lets take a look at another, and similar case .............

The 'Slider' control :

If we look in the Fields section of the 'Slider' UI element, we see no entry for 'Value', and

yet this may be the most required property for binding.

However, under the Properties section we are guided to 'Rangebase' - the class to search on - see below :-

===========================================================================================================

The fields in the RangeBase shown below, are only few :-

=========================================================================

And as you can see we have the 'Value' DP at the bottom of the list.

I will leave it to you to find and view the 'Inheritance Hierarchy' for the Slider control.

As you can imagine, there are heaps of DPs on controls which can be used for binding, so the answer

is as I said at the start "HUGE" indeed.

The secret is to know how to find out if you are in doubt - and the above notes helps you 100% I feel.

Time to move on, see you in the next subsection ..................

PHH - 7th. January 2014..


Some words about 'binding' data types

Some words about 'binding' data types

Some words about 'binding' data types

 Previous topic Next topic

Once we know which property of our UI element we wish to bind to, we need to either find or

make a suitable property on a .NET class object.

By suitable, we mean the data type of the UI element DP must be the same as the property of

our business class object being use as the second part of the 'binding'.

In the case of our 'Width' DP from FrameworkElement, it needs to be a 'Double', or REAL8.

============================================================================================

By now you have probably realised that when we create bindings the actual properties do not really

matter (which they are) as long as the data types are compatible - or match.

So we could have a .NET property called 'nWidth' and which is designed to hold a width value, but we are

able to make a binding with the height attribute / DP, simply because the data types are the same. It

is up to us to get our code and script correct.

In a sense, this is exactly what we do when we bind the 'nWidth' property of a .NET data class to the

'Value' attribute on a 'Slider' UI element - the two are simply the same data type.

PHH - 7th. January 2014..


Binding - one GUI control to another !?

Binding - one GUI control to another !?

 Previous topic Next topic

Binding - one GUI control to another !?

 Previous topic Next topic

So far we have said a lot about keeping values out of the XAML script and firmly in the .NET code.

Well, that is a good idea for what we call, or 'term', "data values", but what about values that determine

the shape and look of UI elements on the screen themselves ?

Those sorts of values we expect to see defined in Styles.

If you don't understand what I mean, then lets take an example.

Line 55 below has height and width values, check this out below :-

================================================================

And if we look at part of a Resources section (on the Window object) we see the following :-

==========================================================================

As you can see above lines 23 and 26 show just these sorts of values.

I would suggest that if the value is not in any way part of your data object, or in MVVM your

'ViewModel' VM object, the keep it within your XAML mark-up.

Either the screen script itself, or part of an external 'Resource Dictionary' object / file.

Colours and fonts, and much more related 'stuff' can be kept out of the .NET code files.

We can do some interesting, and pretty amazing things by having "Intra-binding" of properties

between UI elements.

Lets explore ............

Intra-binding :

We can start with a simple example, a simple idea.

Let us say we are to have three 'TextBox' elements and we need them to always be the same

width and the same height - but we want to be able to change both values at runtime.

So we do not try to do too much in one step, let us start by defining a hard scripted value for both

attributes, but on the first element only.

We can then bind the two properties on the second element to those of the first, and then those of

the third to those properties of the second.

Check this out :-

============================================================================

Notice that to do this 'chained' binding we need to give most of the elements involved a

Name attribute value. 53, 59 and 66 show where the naming takes place.

The above script will mean that all three TextBoxes are 110 units long and 32 units high.

Now then, lets try and get our numerical values from .NET code, instead of being hard scripted.

Check this out :-

==================================================================

Yep! we are calling back into our code behind - but in MVVM this will be the VM or 'ViewModel'.

When we do this we need to be careful or we confuse ourselves, and don't get it to work either.

Check out these details - see what we CAN'T do :-

=================================================================

We need to try some other approach .........

This seen below is different, and works in part - BUT - it is 'fixed' and not 'binding'.

See the following code and a display image at runtime :-

======================================================================

Lets give it a go, and explore things a little to get a feel of what is going on :-

=================================================================

Yes, we do get boxes two and three with the same size as the first one - BUT - we have

not as yet bound the .NET code values to the UI attributes - we have only assigned the

attributes each a value.

If we are going to get the code shown below to work as genuine binding, then we must

construct in .NET code a suitable data object, with suitable public properties.

Check this first to remind ourselves :-

===============================================================

What we bind to in the end, MUST be a public property.

Lets us make our public properties as simply as possible, although we will need to keep to

the accepted ways of making a viable, and working, data class for binding.

Study the following in detail :-

===================================================================================

And now we have a well written code class we call it in our XAML script like this :-

[ .. check line 10 .. ]

===========================================================================================

And the code part of the binding has to be completed in an association with the 'DataContext' property

as we can see below :-

[ .. line 78 is the one to look out for ..]

===========================================================================================

The results at runtime of these specified values can be seen in the next image :-

=============================================================================

And when we change these coded values for the property values we see this :-

=========================================================================================

And then the resultant runtime display of :-

===========================================================

Use the size of the mouse pointer in both purple images to help you gain some sense of scale.

This seems to make sense to me, hope you catch the drift / get what its about etc..

'Final Test' - see if we can force a code change at runtime :

As I may have mentioned a few times in earlier sections, the real test of whether we have our data binding

correct is to force a code change at runtime, and see if the UI display reflects the change(s).

Let us start this last section with an image of success - check this UI display :-

==============================================================

The above appeared after I clicked the button with the mouse.

The click event handler method for the new push Button is as follows :-

=================================================================================

So you know, the display starts out like this - shown below :-

[ .. the button is just about to be clicked .. ]

=========================================================

We need to study the 'Button' XAML script - check it out below :-

===========================================================================

Above we see the Click event script entry for the method named "pbForceCodeChange_Click".

And finally, we can see the code and intra bindings on the three TextBoxes.

Note we are also using an extra set of bindings on the Text attribute - check below :-

==================================================================================

Okay folks, that is that - we seem to have done enough for now. How about a short video ?

Force see 22 and 88 !!

=============================================================

See you in the next sub-section ...........

PHH - 7th. & 8th. January 2014.


Binding - one property to another on the same element

Binding - one property to another on the same element

Binding - one property to another on the same element

 Previous topic Next topic

"SELF binding" is the name for this :

There are times when we may need to bind the property on a single UI element to one of its other properties.

At first this sounds crazy, but then so does SQL 'self joins' using only one table - till we think about it.

Since 'binding' is all about one properties sharing the same value via a pointer (or two) then there is now

reason at all why there should be an issue because the Source and Target properties happen to be on the

same UI element, or control.

As far as I know, with my limited XAML experience, this is more likely to be required for the 'look-feel' of

the screen, and graphical display, than to be that much use with business class data values.

================================================

In the following image line 8 contains the script for 'self binding'.

Translated into 'man-in-the-street' terminology, the source value is the 'Content' property, and this is bound

to the target property of 'Background' on the same 'ListBoxItem' object.

So in our example, the text (word) 'Yellow' is the source and when this value is applied via binding to the 'Background'

attribute we see the resultant yellow colour.

Check out the details in the image below :-

=============================================================================================================================

Although the syntax looks a little crazy at first, it is simple because we are using similar names in

both property and class - just as we often do in .NET code.

In the line numbered 8 above, it is the Path and the Property which really matter to us, the rest is

common to every case of self binding - I think !?

PHH - 9th. January 2014..


Bindings - Creating and changing in .NET code

Bindings - Creating and changing in .NET code

Bindings - Creating and changing in .NET code

 Previous topic Next topic

http://msdn.microsoft.com/en-us/library/ms742863(v=vs.110).aspx

===================================================

Lets get one thing straight, it is MUCH easier to set up our bindings in XAML script.

Creating bindings in .NET code is quite possible (as you will see soon) by is a bit messy and

a little confusing - depending on you point of view.

We can learn a few things by doing some test and trial code bindings however ;-0)

In the following image I have commented the working bindings "script sections" - check this out :-

=================================================================

So when built and run our app, the sliders now have no effect - check the comparative images below :-

=====================================================================================

Both the sliders in the two scenarios have been moved and then left in the exact same places.

The right hand image is generated when the XAML script is commented.

Lets move on to the 'fun' part ..................

Setting up 'bindings' in .NET code :

Let us now see some working code which achieves the same binding results as the simple two

lines of XAML script we have commented out.

I warn you, you need to study it carefully !! Here it is below :-

We have already made and used this code :-

=========================================================================================

So we have instantiated the 'nHeightWidth' object, which can be used as seen in the next image :-

[ .. lines 117 and 122 remind us about Dependency Properties, and the stuff found in the 'Fields'

sections in the Help Viewer SDk docs .. ]

=====================================================================================

In the above code we are setting up two bindings, one for the width on the 'width' slider, and

the other for height on the 'height' slider.

Notice that we instantiate a 'Binding' class object, whose 'Source' property we set to our existing

data object - the one we called 'nHeightWidth'.

In instantiating the binding we have specified a property - one called 'nWidth' like that seen below :-

==============================================================================

Okay then guys, this code compiles and runs - just fine.

But this success opens up some possibilities for us ;-0)

We can cause the bindings to swap over at run time, with a CheckBox, so that the width slider

actually changes the height of the TextBlock, and vice versa.

Yes, I know this example is a bit stupid, but it is useful for us to see how to make and change

bindings, from UI element properties to .NET data object properties, at runtime.

First of all lets see how we can augment (or improve) this code to do the swapping over - check this out :-

=================================================================================

In lines 100 and 105 we have swapped over the properties of the .NET code data object.

Lets now see how we can make the real time interaction work for us.

First lets see our new GUI design surface - check out below :-

=============================================

And this new 'CheckBox' control has the following XAML script - study it thoroughly :-

=============================================================================

And also notice that line 66 has alternative syntax in the above image, and the accepted

'normal' syntax in the following image - see line 66 beneath :-

=====================================================================================

Line 66 looks to be binding the 'IsChecked' attribute to a .NET property on our data object of

'lSwap' and this is a Boolean.

In fact I added this to our class called 'HeightWidth' and the details are here :-

======================================================================

You will also see that in lines 67 and 68 we have chosen to 'set' a couple of events, and that the

event handler methods are specified in blue.

The event handlers are .NET code methods and we can see them in full detail in the next image.

Check these out carefully :-

==================================================================================

Yep! all we are doing when the 'CheckBox' is checked and unchecked, is to run the method called

'DoSwapOver'. This is the one we studied above.

So all we need now is to see a couple of sample (demo) videos - try these :-

Swap-over One

Swap-over two

===============================================

Okay then folks, lets do a 'round up' ................

Summary :

For completeness I have shown you how to code property bindings - BUT - I find XAML script much easier

and cleaner to use.

It would seem that the MVVM 'pattern' is OK with us using script to define our bindings.

I do find code more difficult to get my head around, as it seems easy to confuse oneself (myself).

I get good success with XAML binding.

To do binding in code means we need to give UI elements a 'Name', and that is a BIG 'no no' in MVVM

land (the world of MVVM).

If we have to 'Name' our UI elements / controls the 'Rule 1' of MVVM says we are doing something WRONG.

Bindings are possible if both the properties are of the same data type - even if the binding does not make

logical sense.

lets move on to a new subsection, see you there .....................

PHH - 8th. January 2014.


what is MVVM ?

what is MVVM ?

 Previous topic Next topic

what is MVVM ?

 Previous topic Next topic

Well guys, I went to my local VOUG (Visual Objects User group) meeting last evening, and saw a presentation

by Nick Friend on "MVVMLight" - a walk-through session.

This was well presented by Nick (as always) and did a great job of convincing the assembled 'crowd' that we all

MUST get into MVVM is some way or another.

It also appeared to many that the way to get into MVVM is to take a simple but fully structured, and working,

small app and use this for Copy & Paste adaptations so that we can fashion our own MVVM first app.

Since MVVM is a new 'pattern' for app development we can't easily (at all?) do a bottom-up job, where we gradually

change over bits of code and script in a conventionally structured app.

We are MUCH better to embrace the idea of MVVM and start with the full supporting 'pattern' and take a working app

pattern and make it our own by replacing the parts one for one with our own flavours and varieties of 'stuff'.

Nick has done a lot of work with 'MVVMLight' on his large commercial application. I on the other hand have done

some work with 'Prism' which is the Microsoft MVVM offering.

Be warned ! - there is a LOT of web material out there that makes MVVM seem very complex and is off-putting.

Also the new terminology (and there is a lot of it) means that there is another mental hurdle to overcome - " just what

on earth is this author talking about ? " ;-0)

Making a Start - keeping it simple :

Let us start at the usual place for MVVM, and that is what do the letters mean ?

Here is the way to see it as written down in many web places :-

M - V - VM .......... meaning ... 'Model' - 'View' - 'ViewModel'

Here lies a problem from the start as many of us guys have gotten used to seeing our app solution in layers, starting

with the Data, then the Business Logic, and then the GUI stuff.

This would then map to the 'MVVM' acronym letters as M - VM - V or Model, ViewModel, View.

So we need to take the 'MVVM' as a term - or word if you will - which means a whole concept, or app development

'pattern'.

'Model' is our structure custom data.

'View' is simply our GUI surface.

'ViewModel' (VM) is a complex data class which supports the related GUI (or View).

So we can think of the 'ViewModel' as the "View supporting object". And yes, I will resist making my own acronym

of 'VSO' ;-0)

The V to VM surface is all about binding - most usually 'Data Binding'. XAML does binding VERY well indeed.

Obviously, the View supporting object VM is made from, fashioned out of - the 'Model', or objects from the Data Layer (DL).

Short Summary :

We can think of the View and VM relationship, as a 'one-to-one' type of mapping.

Properties from the VM (or support object) bind directly to UI elements and controls on the 'View' or window / form.

What do we do First ? :

So what do we design first ? - the View or its supporting object ? Is it View first, or ViewModel (VM) first ?

It would appear that this is a matter of choice or personal preference.

I prefer to design and make the GUI form, or 'View' first - to meet the client's needs, or the task required for the user.

On the other hand Nick did his session with designing and making a VM (supporting object) first, then the View.

The choice is up to you, however, it is not a big deal to add some functionality to the View and then edit or update

the VM to keep 100% in-step.

What I can say is that it is a VERY GOOD idea to be organised when you come to do the tasks involved.

Highly Recommended - Read the details in the child folder !

PHH - 7th. November 2013.


MVVM - as seen by following the data !

MVVM - as seen by following the data !

 Previous topic Next topic

MVVM - as seen by following the data !

 Previous topic Next topic

I am going to offer you this view of MVVM as it helps me understand a lot !

It has come to me after MUCH deliberation that the MVVM 'pattern' can be understood quite

easily (and in more depth perhaps) if we "follow the data" as they say ;-)

Simple Question :

When we apply the MVVM 'pattern' correctly, where is the data ?

It seems to me that the answer is "in the Model".

So although we have a View and a bound ViewModel, these have no data (as such) other than

that 'projected' through into the VM at instantiation from the Model.

In the Constructor of the VM the projected Model is used to assign values to the VM properties.

However, this effectively just passes pointers to the VM properties of the objects within the Model.

The objects which are the Model property values have their pointers supplied to the VM properties.

By 'Data Binding' the VM projects the same pointers (and related objects) to the UI control attributes.

No data is held separately in the UI element attributes, and only a few support properties in the VM are

not part of the Model.

When the View and the ViewModel are closed, the Model still exists in memory and with it all the updated

data, as well as all that from initial population.

Any Model is then available for further 'projection' and hence binding, or it can have its data 'dumped' to the

back-end server for permanent storage. This will usually be done by LINQ to SQL or LINQ to Entity Framework.

We the developers write the methods in the Model to update the data server - BUT - this has gotten very easy

in days of the above SQL and LINQ technologies.

So to summarise, although MVVM is always talked about by using words like View and ViewModel, it is the

picture of the data that tells the real story ;-)

Model (data & business logic) >> ViewModel (interactive logic) >> View (bindings)

I hope you find this interesting.

PHH - 20th. November 2013.


the basic 'pattern' of binding - 'View' & 'ViewModel'

the basic 'pattern' of binding - 'View' & 'ViewModel'

the basic 'pattern' of binding - 'View' & 'ViewModel'

 Previous topic Next topic

*** Note *** see the appendix ('C') on "Portable Class Library" !!!

==================================================

http://blog.xamarin.com/mvvmcross-seminar/

================================================================================================================

MVVM - Rule "One" : (don't mess with the data)

Do not hold data values in the View.

Make the View display data values from properties in the ViewModel (VM).

So at any point in time the VM holds the latest state of the application data.

[ .. but since the VM property values are just pointers to the Model property

objects it is the Model which holds the data .. ]

Make the View UI controls / elements reflect the values of the VM properties.

Populate the VM properties by using a Model to 'inject', or as I like to call it "project", existing data values.

VM instantiation will use a Model as 'input parameter' in the Constructor.

MVVM - Rule "Two" : (don't call names)

If you have needed to provide a 'Name' attribute value to any control / element, then you

are not 'doing' MVVM as well as you might !

MVVM - Rule "Three" : (keep it clean)

Remove all code from the 'Code Behind' other than the 'stub' code, AND, remove all logic from the

XAML script as well. Do this latter by only binding attributes to VM properties.

MVVM - Rule "Four" : (don't use Events, but Commands)

If you do all four of the above then you are well on your way to good MVVM applications.

PHH - 18th. October & 20th. November 2013.


Getting data to our 'ViewModel' - "projection"

Getting data to our 'ViewModel' - "projection"

Getting data to our 'ViewModel' - "projection"

 Previous topic Next topic

PHH - 14th. November 2013.


flavours of MVVM - 'Prism' from Microsoft

flavours of MVVM - 'Prism' from Microsoft

flavours of MVVM - 'Prism' from Microsoft

 Previous topic Next topic

PHH - 18th. October 2013.


flavours of MVVM - 'Light' from Laurent Bignon

flavours of MVVM - 'Light' from Laurent Bignon

flavours of MVVM - 'Light' from Laurent Bignon

 Previous topic Next topic

Throughout these eNotes I will refer to MVVMLight as 'MVL'.

This is just a personal choice to make both writing and reading eNotes on MVL much easier ;-0)

In building my 'Walk-through' samples for latter in these notes I have used two GalaSoft 'dlls' which

came directly from Nick Friend's small working sample - the one he presented at the VOUG meeting

at the start of November 2013 - in Bristol.

I just copied and pasted them from his solution into my own new project - see below :-

===========================================

Yes, the above is my sample - an app called 'WpfMVLstart' - remember I use MVL to mean

MVVMLight.

What you guys need - to move into MVL :

Try a Google with "galasoft mvvm light nuget" as I have done below :-

=========================================================================================

There are many results and a few should bring you to the following screen :-

=======================================================================================================================

=======================================================================================================

=========================================================================================================================================

==================================================================================

Trying this with a completely new project, in the brand new VS 2013 of just yesterday's download / install,

we get the following after using the app template :-

=================================================

Remember this is VS 2013 and so the following is similar to that show previously, but different.

Check it out thoroughly :-

==================================================================================================

======================================================================================================================

===================================================================================

======================================================

=============================================

=============================================

PHH - 14th. November 2013.


what do we need from the Galasoft DLLs ?

what do we need from the Galasoft DLLs ?

 Previous topic Next topic

what do we need from the Galasoft DLLs ?

 Previous topic Next topic

Controller :

=====================================

===================================================================

=========================================================================================================

===============================================================

View :

=====================================================================================================================

VIEW : - From Nick's more Advanced Example :

>> Coming to this - needed in View (XAML) : <<

=============================================================================================================================================

================================================================================================

===========================================

ViewModel :

==================================================================

================================================================================================

=================================================================

===================================================================

===================================================

======================================================================

Properties :

=====================================================================

==============================================================================

Commands :

=========================================================================================

================================================

Methods :

============================================================================================================

Model :

=================================================================

PHH - 15th. November 2013.


Vulcan with MVVMLight / MVL

Vulcan with MVVMLight / MVL

Vulcan with MVVMLight / MVL

 Previous topic Next topic

Although I have not tried MVL as yet with Vulcan.NET 3.0, I would imagine that it will work

a-okay, as we only need a couple of DLL assemblies to support it.

The Galasoft DLLs we have seen in the parent folder should work like C# class libraries in other

Vulcan projects I have developed.

I will try MVL soon with VN3 in VS2012 - as the integration from Fabrice for VS 2013 is not yet

released for us guys to use.

=====================================================================

Good News - we have Success !!!

Yes guys, we can do MVVMLight with Vulcan 3 - below is the runtime proof :-

===================================================================================

You can find out all the necessary details in the relevant 'walk-through' sections later in

these eNotes.

For now just check out the SE pane shown below - this is for a working copy of the C#

application developed in the first 'walk-through' section :-

==============================================

PHH - 14th. November 2013.


What is Reflector 8 - from Redgate ?

What is Reflector 8 - from Redgate ?

 Previous topic Next topic

What is Reflector 8 - from Redgate ?

 Previous topic Next topic

Well guys, I am no expert on things other that .NET and high level programming / development.

I know little of 'MSIL' except in concept - "Microsoft Intermediate Language", a programming language that has

been standardized later as the 'Common Intermediate Language'.

However, I find 'Reflector 8' an excellent tool for working in C# and VN3 - singly and in a mixed solution format.

I find being able to look into assembles for MVVM and WCF services, a great benefit.

Using Reflector 8 I can see inside DLLs and the likes, to see member details, and parameters used etc..

Also with Fabrice's plug-in I can translate back and forth from C# to Vulcan.NET - a great help.

I suggest you invest some cash a buy the professional version - well worth it.

=========================================================================================================

Here is a useful link :-

http://www.red-gate.com/products/dotnet-development/reflector/

And here is a graphic related to the product :-

============================================================================================

Now check out some of the following details :-

====================================================================================================

And here are a few more :-

===================================================================================================================================================

=====================================================================================================

=========================================================

It is worth you reading my notes and comments in the sub-section to this section.

See you there ....................

PHH - 2nd. January 2014.


Setting it up for Vulcan.NET

Setting it up for Vulcan.NET

Setting it up for Vulcan.NET

 Previous topic Next topic

Once you buy and download the professional version of R'eflector 8', it will install itself both as a

stand alone as well as within Visual Studio itself - 2012 and 2013.

It should then just work as Redgate intended it to.

BUT - for us guys interested in Vulcan.NET (2 and 3) we can go that step further.

Here is a web link to Fabrice's web site - 'Fabrice Foray' at "FabToys" :-

http://www.fabtoys.net/downloads/cat_view/26-vulcan-net

Unfortunately, the following (current?) web site features, do not seem to include the DLL for version 8 - the one

I am using, and the one he gave to all attendees at DevShare13 in October.

I have just joggled his elbow to remind him ;-0)

=========================================================================================================================================

===========================================================================================================

===========================================================================================================================

==================================================================================================================

PHH - 5th. January 2014.


Stand alone use

Stand alone use

Stand alone use

 Previous topic Next topic

==================================================================

===================================================================================================================

==================================================================================================================

===========================================================================================================================

PHH - 2nd. January 2014.


Use from within Visual Studio

Use from within Visual Studio

Use from within Visual Studio

 Previous topic Next topic

====================================================================================================================

===============================================================

==============================================================

===============================================================

========================================================================

======================================================

======================================================

=======================================================

=====================================================

PHH - 5th. January 2014.


Walk-through exercises with VS 2012/2013

Walk-through exercises with VS 2012/2013

Walk-through exercises with VS 2012/2013

 Previous topic Next topic

PHH - 21st. October 2013.


Example (C#) - swapping 'UserControl's in and out

Example (C#) - swapping 'UserControl's in and out

Example (C#) - swapping 'UserControl's in and out

 Previous topic Next topic

Okay guys, this next Walk-Through example is a good one, and one which is hopefully taking

us towards MVVM and the 'pattern' of development it encompasses (encloses?).

Remember that a UC (User Control) is like a mini form / window, and that a ContentControl (CC) on a

single form / window, can have a UC displayed within it.

It is easy to change the UC displayed in a single CC, so that we effectively have many forms within

a single form.

If you are not sure what I mean, then just follow the detailed information I provide and see how it turns

out in the end.

Making a Start :

Open Visual Studio 2012 and close down any open solution or file(s).

Use - File, Close solution ............

From the menu bar choose :- File, project ... as seen below :-

=========================================================================================

When the 'New Project' dialog screen appears, select the Template as shown in the following image :-

===========================================================================================================================

Notice above that we are selecting a C# WPF windows template, and that we have named it "WpfCSswapUCs_01".

We will make a Vulcan equivalent sometime later - but the flavour of the .NET language is not a big deal for what

we are doing here.

Also note above that I am using TFS (Team Foundation Server) for version control, as I always do these days, so

I have checked the box at bottom right of screen.

If using TFS you will get an option dialog screen to allow you to use an existing folder, or make a new one - check

the next two images to see what I get here :-

====================================================================================================================================

If you do all the above correctly then you will see the following details in the SE (solution explorer) pane.

Check this out :-

=====================================================

From the above SE pane we are going to select in turn the '.xaml' file and then

the '.xaml.cs' files - to display in the editor.

Here is what the first one looks like - check below :-

=========================================================================================

And now the .NET code file '.xaml.cs' is seen to be like this :-

==========================================================

So as you can see, we have very little at the moment - we need to start adding our own 'stuff'.

Going a Step Further :

Before we add any UI elements to the new WPF form (Window), let us make a few useful changes

to the Window attribute vales themselves - checkout below :-

=================================================================================

The XAML script changes are in the following image :-

==============================================================================================

Before we try to add any UI elements - Buttons and 'ContentControl', it will be most helpful to add

a few rows and columns to our grid.

Type directly into the XAML editor, between the 'Grid' tags - you copy, as seen below :-

===================================================================

Okay then folks, now that we have a working Grid set out ( 7 by 7 ) we can now add some

other UI elements ..........................

Adding GUI controls to the Gird :

From the Toolbox find and drag a 'ContentControl' element onto the graphical designer surface.

As seen below, drop the drag in the second row and third column :-

=======================================================================================================

When you complete (finish) the drag from the Toolbox, you may see something like the following :-

=========================================================================

Now then, before we examine and explore the script for the CC and other stuff we are to add, we

need to collapse the Grid row and column definition lines.

Remove any empty lines between columns and rows, and then use the little control boxes (showing '-' )

to collapse the required sections - the control box should now show a ' + ' sign in each.

Here is what I have :-

=====================================================

Now we can hide a few lines in the script header area - the next image should indicate just where we

need to highlight, and then from a right click context menu, that we need to select 'Outlining, Hide Selection'.

Here is what I see before I click to finish the selection :-

===============================================================================================================

If you get this right you will see the following in your text editor :-

============================================================================

Yes, note that in the above image I have also made some editing changes to the CC attributes.

This gives me the following :-

=======================================================================================================

If your CC does not seem to be snapped to the grid lines you may need to use the mouse pointer to drag the corners.

This should not happen, but my VS2012 seemed to get itself a bit mixed up when I did this. It seems OK now however.

Now then, lets make the biggest change yet - small but VERY important ;-0)

========================================================================

On line 26 we need to set the Content attribute value so that it is set for binding.

When we get there (soon) we will bind out 'UserControl' objects to this CC. But we have other

things to do first.

Building and Running the app :

If we do a build and run at the moment, we will see absolutely nothing on our window. And that

is because our CC has no colour or content, so it is transparent.

We can use a little trick or technique to put this right, and to help us see where the CC should appear.

Let us put a coloured Border around our CC - checkout the following details :-

==================================================================================

Now tidy up some of the script lines for the 'Border' element - see below :-

=====================================================================================

Now when we do a build and run we see something like the next image :-

==========================================================================

Lets move on and add our first Button .............

Adding three Buttons :

Okay guys, once we can suitably add our first Button to the form, we can easily then add a second,

and a third as well.

Drag a Button from the Toolbox onto the grid position row 2 and column 1, then change / adjust the XAML

script to be as seen below :-

======================================================================================================

Note also that we have now gotten an event attribute called 'Click' - so that the associated method handler

'pbCustomer_Click' will be run when the click event fires on this Button.

Here below is the portion of the Properties pane with the top right 'lightning' icon selected :-

===========================================================

When I double clicked in the empty (vacant) input box for 'Click', it got an 'auto-fill' with this name, simply

because of the name of the Button and the event title/name as well.

The editor will also auto-jump to the code behind file to reveal the following 'stub' of the method code added :-

==================================================================================

Lets keep on moving .............

More Buttons :

While we are 'in the grove' for adding a Button, let us add two more Buttons.

I have elected (chosen) to do this by copying and manually editing the Button code we already have.

Lot at what I now have in the XAML text editor, and then we can discuss the 'Click' events etc..

Check this out carefully :-

===========================================================================================

As you can see in the above code, I had to change the row values on lines 45 and 52, to 2 and 3.

The Name of the two new Buttons was also manually edited, as well as the 'Content' attribute value.

While doing the manual editing, I removed the 'Click' event and the associated method name from lines

48 and 55.

Once the basic editing was completed I placed the text cursor within the second button and then used

the auto-generate feature from the Events list in the Properties pane.

With the editor showing the .NET code file I pressed 'Ctrl+ -' (said control and minus sign) to cause the

editor to re-show the XAML script. Yes, 'Ctrl+ -' is very useful to step back to where the cursor was last

in the editor - this also works across different text files as well as within a single text file.

With the editor showing XAML I then repeated the auto-generate process, this time with the cursor within

the third Button text.

Now then, build and run the app to see that all is still 100% okay - here is mine :-

===================================================================================

You should now have three empty 'stubs' in the .NET code file as seen below :-

=========================================================================================

For the moment lets us leave these empty, and go and tidy our XAML script, as far as the Buttons

script is concerned.

Tidying our XAML script :

Okay folks, this is now an important part of the design and create process, as we are actively making

a new app as opposed to talking about how code and XAML stuff works.

We need to keep our script clean and tidy, and easy to read, in our XAML edit section.

Check out the following new entry lines - 7 through 16 :-

================================================================================

With the above lines in place we can now remove a lot of stuff from the attributes of the three Button

sections in our XAML script.

Check below to see how it now looks in XAML, as well as that the Design surface still looks as required :-

========================================================================================

Only those attributes and their values, which don't change from Button to Button, need to be

specified in the 'body' of our main Grid script.

Let us now move on a BIG pace ..............

Creating our first 'UserControl' :

Okay you guys, since we are to have three UCs which we can switch in and out of our CC element,

we now need to move on to creating our first one - then we can check if it 'binds' okay.

So lets get to work with creating the UCs.

Place the mouse cursor in the solution item / node, within the SE pane, and bring up the context menu

with a right click - select to add a new project - see below :-

===================================================================================================

Input a name of "WpfControlLibrarySwap", having selected the suitable Template for C# and Windows WPF.

When you click OK and have gotten all things right you will see the following - check this out :-

=================================================

Open up the UserControl node and select the '.xaml' file to be displayed in the editor :-

=============================================

You should now see the graphical designer surface looking pretty empty - like seen below :-

=========================================================================================

Note that the main object/class 'Tags' are for 'UserControl' and not 'Window'.

Lets leave the width and height attributes on the UC as 300 by 300 for the moment.

Before we start the detail - lets see some success :-

=================================================================================

Yep! we certainly have something appearing in our 'ContentControl', and it is 'thistle' coloured.

Let us see how we managed to do this, even though it is a simple way, which we will change

very soon.

Checkout these details :-

=======================================================================================

So if we build and run the app, then the UC is seen bound to the CC (or we can say seen within

the CC), right from when the app screen is displayed.

We can change this to be controlled by Button clicking soon below.

First of all lets see the Designer graphical surface for UC1 (User Control 1) - note that there is an

Image control towards top right of the UC area :-

========================================================================

The above image shows we have coloured the UC background, given it a name of "ucCustomer",

and have limited the size to 300 by 300.

Lets move on, and improve things a little, we can move the display of the UC1 object to the customer button

click method - just as seen below :-

=================================================================================================

The above change will mean that nothing is bound to the CC at runtime, and only when the 'Customer' Button is

clicked will we see the UC come into view !

Here is the opening screen at the moment :-

==============================================================================

WE also have to do something about our UC object only partly showing through the CC space

on our main window.

I have done some simple testing to find that with a 300x300 shape of UC we can best show these

with a main form set as seen below - with some extra rows and columns, and the 'span' values changed :-

=======================================================================================

After the few extra changes we see this in our designer surface :-

===========================================================================

And once we build and run with these changes we see an improved 'fit' as shown in

the following image :-

===================================================================================

Moving on ...............

Adding a Photo image :

let us now do something about our missing photo from the Image control we have on our UC

at the top right of UC area.

Make a new folder under the library project node - the fill it with three or four image files from

existing 'other' folders - like 'Pictures' - here is what I have :-

===============================================

Make sure that the Build Action is set to 'Resource'.

So now we can use one of these as 'Source' to the Image control. Here is the blank Image in

our design surface :-

======================================================================

And if we make this control 'in focus' then the Properties pane allows us to select an image.

Check below how we can make suitable settings :-

==========================================================

Now we can see our new selected image / photo in the designer :-

==========================================================================

"Good photo Dai ! "

Now when I do a build and run, and then click the 'red' button, we see this - a definite

improvement I feel :-

====================================================================================

Yes, I know, we still need to improve the UC1 (class) itself, but at least we are getting the

right behaviour.

Moving on again ..............

Adding the 2nd & 3rd UserControls :

At the moment we have our SE pane looking like that seen below :-

============================================

We can see above the 'UserControl1.xaml' file, and we now need to make two more

which are similar.

Here is what I get when I right click the library Project node for a context menu :-

================================================================================

Yes, there is a convenient UC option in the sub-menu, as seen above.

Selecting the option shown above we then see the 'Add New Item' screen - like that below :-

================================================================================================

If we use this dialog screen a couple of times, and enter 'UserControl2' and 'UserControl3', then we

end up with a SE pane contents showing the following :-

=================================================

Yes, we can now see three UserControls in the top project area / section.

Before we move on to the 2nd and 3rd UCs, to 'flesh' them out with suitable UI element contents, lets

finish and tidy the first one to look as seen in the next image :-

=============================================================================================

Yes, we now have a few initial data settings, as well as the correct colour background - one to match

the colour of the Button to be clicked.

When we build and run we get this shown below :-

==============================================================================

And before we have a break, before moving on to the last two UCs, let us checkout the .NET code to

initialise the UserControl1 class / object :-

================================================================================

The above data provision and binding is rather simple, or Mickey Mouse, but it is good enough for

the moment, and for early tests.

Remember, that the point of the exercise is to have three UCs which swap in and out, not a real

fancy Data Binding to the UC itself - however, we will improve things at least a little ;-0))

Finally before we have a break, here is the partly tided XAML script for the UC1 object / class :-

===========================================================================================================

Yes, I know, in the above script we can still do a lot more to tidy and clean the script - I will do this now, as it

will save us some time and effort when we come to creating the XAML script for 'UserControl's two and three.

Tidying the Script before moving to UC 2 and 3 :

Okay then guys, let us now see just what can be done to tidy and organize our existing script.

Lest go about this 'backwards' - let us look in detail at the tidied 'body' of our XAML script for UC one.

Check this out thoroughly :-

============================================================================================================

The above image is of the tidied script - with its header lines collapsed, as well as the Resources section which

we will examine in a moment.

Although we have few UI elements of each type (except the 'RadioButton's) it is worth me making the effort to

move basic attributes and their values to the 'Resources' section.

We will be able to use these entries in the Resources section over again in our next two 'UserControl' declarations.

Now then, there will be those amongst you who think that the script lines in the image below are at least as long

or as complex, as those we have replaced - so why the bother ?

I suggest you wait and see just how tidy and organised using such an approach can make our script, the creation

process, and also how easy it is to copy sections of 'Style' lines from one UC or Window to another, so that retyping

is not required.

Even while typing the Styles the first time we can copy and re-use lines from different sub-sections.

Checkout carefully the following script lines :-

==================================================================================

Note in lines 34 and 41 some more special settings !

Let us now copy this 'Resources' section so that we may use it to create UC2 in a few moments.

Starting to make UC2 - called "Product" :

First of all, to our almost empty 'stub' XAML script file for 'ucProduct', copy the whole of the Resources

section from the previous UC1 script file.

Here is how it looks (and it is included in the working script and code sub-section) :-

======================================================================================

Even though we do not as yet know if we will need all of these, we may as well copy them, so

that we can adapt them later, or even remove some completely.

To my mind it seems like a good, quick and easy, start to scripting our UC2 declaration.

Setting a suitable Grid on UC2 :

Okay the folks, yet another way to save time, effort, and typing.

Go to the main window of our developing app and copy the Grid definition lines for rows and columns.

Now paste these into our growing UC2 script - my efforts to do this are see below :-

===========================================================

Note above that I have left the rows section collapsed, and that I have edited line 46 slightly

from what it held as the comment.

With the grid lines in place I will now add a few suitable UI elements to make up a reasonable

test / demo scenario for our UserControl '2'.

Before we go any further however, we need to improve our Images folder, by providing sub-folders

and finding some good images from Google 'Images'.

Let see what can be done .................

Adding some suitable images files :

We need to take some time aside to improve the structure in our SE pane. We need to have a better

structure of sub-folders for holding images relating to Customers, Products, and Supplier.

It is a VERY good practice to keep your SE pane well structured, and so contents of folders and sub-folders

do not get too large (or long as displayed on screen).

This is what we are after - check below :-

========================================

Notice in the above image that we no longer have files under 'Images', and now all image files (.png, .jpg ... )

are placed under one of the three new sub-folder nodes.

Here is and example of my Products folder / node :-

==========================================

We make a new sub-folder by right clicking in the 'Images' node to bring up the context menu.

Then select 'Add, New Folder ... '. Then provide a suitable name like 'Products', 'Suppliers' etc..

You will need to move the existing customer images from the 'Images' folder to the new 'Customers'

sub-folder - so highlight these and then drag and drop into 'Customers. That is what I did.

Now use Google and the Images option, search and find images for Products and Suppliers, then

select and 'Save As'.

Right click over each of the sub-folders and add existing files, navigate to those you just saved, and

make sure they are imported (copied) into the correct sub-folder.

With this done and complete, we can now move on to using them in our XAML scripting. But first

we need to correct our previously working Customer UC1 file.

Here is our new folder / node structure :-

========================================

So the existing script text for the 'Source' attribute on the Image control in the Customer UC is not correct

any longer - it needs to be edited (extended) to look like the following :-

======================================================================================================================

In the above image we have added "/Customers" into the path for Source.

You need to do similar and the build and run. If you have done all correctly then you will see

a suitable image / photo on the UC, otherwise nothing - a blank!

Actually, you can see a positive result in the designer surface itself, before runtime.

Here is an example using Marc in place of Dai :-

=====================================================================================

Now then folks, life just seemed easier - BUT - when we use the Visual Studio properties pane

we see a slight problem - check this out below :-

==============================================================

Yes, we now see all of the 'Images' sub-files in one long list. There seems to be an issue (perhaps)

as I also gotten some odd behaviour in the PP after I had just made the sub-folder structure.

Maybe this will improve in future versions of VS - I need to check the pre-release version of VS 2013.

However, all is not lost, as the tool-tip from hovering over the image items does at least guide us as

to which folder the file resides in - so we know its classification. Check this below :-

==================================================================

So above we can see that the highlighted item is actually in the 'Suppliers' sub-folder.

Lets move on .............................

Getting back to UC2 - products :

Before we check out how to do it, here is an image of what we are after :-

===========================================================

On the Image control shown above we have place a suitable Product image / photo, by

selecting from the PP as will will see below.

Make sure that the Image UI element / control is in focus, that it shows on the designer surface

with its resizing 'handles' visible.

Then move to the PP usually at bottom right of my screen, to see this shown below :-

================================================================

The above detail shows when we click the little black down arrow head symbol at the RHS

of the 'Source' property input box. In the image I am about to select the shown item by a mouse click.

Here is what we get after selection :-

=============================================================================

Okay folks, lets move on ...........................

The rest of the UC2 controls :

Having dragged an Image control onto the new UC2 design surface, and given it a Source of an image,

we can now drag and drop a few more suitable UI elements / controls onto the same surface.

After selecting and dropping a few controls my XAML script looks a bit of a 'mess' or nightmare - check below :-

================================================================================================================================================================================

Yep! this is the sort of stuff which made we want to run away and hide ;-0)

Now let us go to our copied 'Resources' section, and change the RadioButton entry to one suitable

for use with CheckBox elements. Check this out below :-

=================================================================================

And we also need a Style for our 'DatePicker' control - we can copy, paste and adapt as follows :-

==================================================================================

With both of these in place we can then revisit the body of the XAMl script and make it clear, clean, and

easier to read - check this out :-

=========================================================================================

Well guys, I think we have an improvement - by removing the relatively unimportant (or fixed

valued attributes to the Resources section, we can more easily focus on those values that we

need to specify to fit our desired US / screen.

Here is what we get so far, at run time :-

===================================================================================

We need to improve the data and value settings of this UC2 object as it opens - the

default values - we can think of them as !

Before we move on to sort out our initial data and values, let us check that 'build and run'

still works as it ought, and then we can use TFS to save (or check-in) our version as it stands.

Yes, mine works just fine, so :-

================================================================

And after saving or checking-in we see on my PC platform the following :-

================================================================

Moving on a pace ........................

Improving the Initial Data and values - UC2 :

It does not take much effort or a lot of time to add some suitable values and data etc..

Here are the few lines of .NET code - many copied and adapted from UC1 - check this :-

================================================================================

I have had to make a few small changes to the XAML script to accommodate the above code.

Now check the XAML script and compare with the previous version :-

==========================================================================================

With both the DateTimePicker and the ComboBox controls I have made changes which will

show up nicely at run time - BUT - please remember that we will 'bind' a proper Custom class

object when we come to do data binding in a more 'correct' manner, as we move towards MVVM.

Binding separate values, and individual collections is NOT the best way to do this in the end ;-)

But study what we get when we run and then click with the mouse the 'Product' button.

============================================================================================

At the click of the 'Product' button an UC2 object is instantiated and then bound to the 'ContentControl'

of the main window.

During instantiation the values and data are 'set' - here are some more to study :-

=============================================================================================

Okay then folks, things are looking pretty good.

We now just need to repeat this UC2 'process' in order to make the 'Supplier' oriented UC3 control.

See you back here after I make something suitable ;-0))

Lets move on ........................

UC3 - the Suppliers 'UserControl' :

Okay guys, a lot of what I just did was in many ways a copy, or duplication of what we have already

done, and seen above.

Here is what I have ended up with at run time, and after clicking the green Button for Suppliers :-

=========================================================

And yes, this time I have remembered to rename the 'GroupBox' header ;-0)

I have also changed that in the first UC, for Customers :-

============================

You will be very interested to know that while 'assembling' the XAML script for UC3 I did a fair bit

of copying and pasting from both UC1 and UC2.

I started with the Grid row and column definitions, as well as the Resources section - check this out :-

=========================================================================================

Yep! because of how XAML works (it is a mark-up script), as soon as we have some text that makes

sense to the parser / IntelliSense system, we get the result shown in the designer surface - as we see

in the above image.

Below we some more development of UC3 as I copy and paste the script for the 'GroupBox' and its three

'RadioButton's - from the UC1 file - check the details below :-

============================================================

We need to change the header on the GB, as well as the 'Content' attribute values.

These changes are in the script displayed in the following image :-

==================================================================================================================

And when we collapse the GB we can see the rest of the script elements that I have added, many by copy

and paste, then editing to suit :-

=============================================================================================================================

Yes, I know, the above image could be even tidier, but it will do for now. And that is one job you can do

to help yourself learn 'scripting' ;-0)

So then folks, how do we code the 'code behind' for the UC3 user control screen ? What do we need to do in code

which sets up the UC3 class ready for display ?

Below is a simple and easy way of getting together, ready for display purposes. Note that we will soon see, via

another 'walk-through' exercise, a more modern MVVM type approach to the UC data object which is bound.

For now just checkout the following :-

======================================================================================

Fine then guys, just about done as far as swapping User Controls in and out of Content Controls

is concerned.

Let us move on to the next sub-section in which we will vastly improve our data binding part of using

User Controls.

[ .. First you may like to checkout the child section from here, to see the way NOT to do it these days .. ]

See you there ........................

PHH - 2nd. - 5th. November 2013.


'binding out of the box' - before the MVVM 'pattern'

'binding out of the box' - before the MVVM 'pattern'

'binding out of the box' - before the MVVM 'pattern'

 Previous topic Next topic

Okay then guys, one thing about seeing how things should NOT be done, is that this then often

helps us understand the finer, and better, points of how things OUGHT to be done.

It may help us appreciate the MVVM 'pattern' of development if we look at how we did things a little

while ago. And I include myself in this statement - yes, I used to do it all wrong, and thought I was

clever in doing it that way - now wrong could I be ? ;-0)

PHH - 21st. November 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

=====================================================================================

<Window x:Class="WpfCSswapUCs_01.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Swapping UCs - in/out of a CC :"

        Height="400" Width="600" Background="Bisque">

    <Grid>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

    </Grid>

</Window>

=====================================================================================

<UserControl x:Class="WpfControlLibrarySwap.UserControl1"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             Name="ucCustomer" Background="LightCoral"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Image HorizontalAlignment="Left" Height="97" Margin="190,10,0,0"

               Name="imgUC1" VerticalAlignment="Top" Width="100"

               Source="Images/DaiDarkins.jpg" Stretch="Fill" />

        <Button Content="Save" HorizontalAlignment="Left" Name="pbSave"

                Margin="215,270,0,0" VerticalAlignment="Top" Width="75" Click="pbSave_Click"/>

        <GroupBox Header="GroupBox" HorizontalAlignment="Left" Height="110" Margin="10,166,0,0"

                  VerticalAlignment="Top" Width="129">

            <StackPanel Orientation="Vertical">

                <TextBlock/>

                <RadioButton Content="Old :" HorizontalAlignment="Left" Height="26"

                             VerticalAlignment="Top" Width="90"

                             Name="rbOld" />

                <RadioButton Content="New :" HorizontalAlignment="Left" Height="26"

                             VerticalAlignment="Top" Width="90"

                             Name="rbNew" />

                <RadioButton Content="Remove :" HorizontalAlignment="Left" Height="26"

                             VerticalAlignment="Top" Width="90"

                             Name="rbRemove" />

            </StackPanel>

        </GroupBox>

        <ComboBox HorizontalAlignment="Left" Margin="10,55,0,0" VerticalAlignment="Top"

                  Name="cbxUC1" Width="129" ItemsSource="{Binding}"/>

        <Label Content="Company :" HorizontalAlignment="Left" Margin="10,25,0,0"

               VerticalAlignment="Top" Width="129"/>

    </Grid>

</UserControl>

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

//---------------------------------

namespace WpfControlLibrarySwap

{

    public partial class UserControl1 : UserControl

    {

        public UserControl1()

        {

            InitializeComponent();

            //--------------------------------------

            List<string> aList = new List<string>();

            aList.Add("Thomas");

            aList.Add("Richard");

            aList.Add("Henry");

            this.cbxUC1.DataContext =  aList;

            this.cbxUC1.SelectedIndex = 1;

            //--------------------------------------

            this.rbRemove.IsChecked = true;

        }

        private void pbSave_Click(object sender, RoutedEventArgs e)

        {

        }

    }

}

=====================================================================================

<Window x:Class="WpfCSswapUCs_01.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Swapping UCs - in/out of a CC :"

        Height="440" Width="600" Background="Bisque">

    <Grid>

        <Grid.Resources>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left"/>

                <Setter Property="VerticalAlignment" Value="Top"/>

                <Setter Property="Grid.Column" Value="0" />

                <Setter Property="Grid.ColumnSpan" Value="2"/>

                <Setter Property="Width" Value="111"/>

                <Setter Property="Height" Value="32" />

            </Style>

        </Grid.Resources>

        <Grid.ColumnDefinitions>

            <!--nine equal Cols for UC 300 width-->

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <!--nine equal Rows for UC 300 height-->

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

        <Border Grid.Column="2" Grid.Row="1"

                Grid.ColumnSpan="5" Grid.RowSpan="7"

                HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

                BorderBrush="DarkBlue" BorderThickness="4">

            <ContentControl Name="ccSwapping" Content="{Binding}"

                            HorizontalAlignment="Stretch"

                            VerticalAlignment="Stretch"/>

        </Border>

        <Button Content="Customer" Background="LightCoral" Grid.Row="1"

                Name="pbCustomer" Click="pbCustomer_Click" />

        <Button Content="Product" Background="LightBlue" Grid.Row="2"

                Name="pbProduct" Click="pbProduct_Click" />

        <Button Content="Supplier" Background="LightGreen" Grid.Row="3"

                Name="pbSupplier" Click="pbSupplier_Click"  />

    </Grid>

</Window>

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

//-----------------------------------

using WpfControlLibrarySwap;

namespace WpfCSswapUCs_01

{

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

            //----- move the UC binding to the event handler methods -----

            //UserControl1 oUC1 = new UserControl1();

            //this.ccSwapping.DataContext = oUC1;

        }

        private void pbCustomer_Click(object sender, RoutedEventArgs e)

        {

            UserControl1 oUC1 = new UserControl1();

            this.ccSwapping.DataContext = oUC1;

        }

        private void pbProduct_Click(object sender, RoutedEventArgs e)

        {

            UserControl2 oUC2 = new UserControl2();

            this.ccSwapping.DataContext = oUC2;

        }

        private void pbSupplier_Click(object sender, RoutedEventArgs e)

        {

            UserControl3 oUC3 = new UserControl3();

            this.ccSwapping.DataContext = oUC3;

        }

    }

}

=====================================================================================

<UserControl x:Class="WpfControlLibrarySwap.UserControl1"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             Name="ucCustomer" Background="LightCoral"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="RadioButton" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="90" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="75" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="ItemsSource" Value="{Binding}" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="100" />

                <Setter Property="Width" Value="100" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

        </Grid.Resources>

        <Image Name="imgUC1" Margin="190,10,0,0" Source="Images/DaiDarkins.jpg" />

        <Button Name="pbSave" Content="Save" Margin="215,270,0,0" Click="pbSave_Click"/>

        <GroupBox Header="Type &amp; Action :" HorizontalAlignment="Left" Height="110" Margin="10,166,0,0"

                  VerticalAlignment="Top" Width="129">

            <StackPanel Orientation="Vertical">

                <TextBlock/>

                <RadioButton Name="rbOld" Content="Old :" />

                <RadioButton Name="rbNew" Content="New :" />

                <RadioButton Name="rbRemove" Content="Remove :" />

            </StackPanel>

        </GroupBox>

        <ComboBox Name="cbxUC1" Margin="10,55,0,0" />

        <Label Content="Company :" Margin="10,25,0,0" />

    </Grid>

</UserControl>

=====================================================================================

<UserControl x:Class="WpfControlLibrarySwap.UserControl2"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             Name="ucProduct" Background="SkyBlue"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="RadioButton" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="90" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="75" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="ItemsSource" Value="{Binding}" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="100" />

                <Setter Property="Width" Value="100" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

        </Grid.Resources>

    </Grid>

</UserControl>

=====================================================================================

<UserControl x:Class="WpfControlLibrarySwap.UserControl2"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             Name="ucProduct" Background="SkyBlue"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="CheckBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="100" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="75" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="ItemsSource" Value="{Binding}" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="100" />

                <Setter Property="Width" Value="100" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

            <Style TargetType="DatePicker" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="33" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="133" />

            </Style>

        </Grid.Resources>

        <Grid.ColumnDefinitions>

            <!--nine equal Cols -->

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <!--nine equal Rows -->

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

        <Image Grid.ColumnSpan="3" Grid.Column="6"

               Grid.Row="1" Grid.RowSpan="3"

               Source="Images/Products/imagesM6EIIJJQ.jpg" />

        <Label Grid.ColumnSpan="4" Content="Product Items :"

               Margin="0,0,0,0" Grid.Column="1"/>

        <ComboBox Name="cbxUC2" Grid.ColumnSpan="5" Grid.Row="1"

                  Grid.Column="1" Width="150"/>

        <CheckBox Name="chbxQuality" Content="Quality :" Grid.Column="1"

                  Margin="10,10,0,0" Grid.Row="3" Grid.ColumnSpan="3" />

        <CheckBox Name="chbxGoodPrice" Content="Good Price :" Grid.Column="1"

                  Margin="10,10,0,0" Grid.Row="4" Grid.ColumnSpan="3" />

        <Button Name="pbSelect" Grid.ColumnSpan="3" Content="Select"

                Grid.Column="6" Grid.Row="8" Click="pbSelect_Click"

                Background="LightCoral"/>

        <DatePicker Name="dtpProduct" Grid.Column="1" Grid.Row="6"

                    Grid.ColumnSpan="5" DisplayDate="{Binding Mode=OneWay}" Width="167" />

    </Grid>

</UserControl>

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace WpfControlLibrarySwap

{

    public partial class UserControl2 : UserControl

    {

        public UserControl2()

        {

            InitializeComponent();

            //--------------------------------------

            List<string> aList = new List<string>();

            aList.Add("Large flat box");

            aList.Add("Small cylinder - brass");

            aList.Add("Mediun large sphere");

            aList.Add("Ball of String - plastic");

            this.cbxUC2.DataContext = aList;

            this.cbxUC2.SelectedIndex = 3;

            //--------------------------------------

            this.chbxQuality.IsChecked = true;

            this.chbxGoodPrice.IsChecked = true;

            this.dtpProduct.SelectedDate = new DateTime(1949,03,21);

        }

        private void pbSelect_Click(object sender, RoutedEventArgs e)

        {

        }

    }

}

=====================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace WpfControlLibrarySwap

{

    public partial class UserControl3 : UserControl

    {

        public UserControl3()

        {

            InitializeComponent();

            //--------------------------------------

            List<string> aList = new List<string>();

            aList.Add("Flat bed loader Co. Ltd.");

            aList.Add("Forklift United.");

            aList.Add("Bulk Carrier Ltd.");

            aList.Add("Containers, Boxes & Parcels");

            this.cbxUC3.DataContext = aList;

            this.cbxUC3.SelectedIndex = 2;

            //--------------------------------------

            this.chbxQuality.IsChecked = true;

            this.tbxSuppliers.DataContext = "There is a better way ..";

            this.dtpSuppliers.SelectedDate = new DateTime(1966, 06, 22);

            this.rbNational.IsChecked = true;

        }

        private void pbKeep_Click(object sender, RoutedEventArgs e)

        {

        }

    }

}

=====================================================================================

<UserControl x:Class="WpfControlLibrarySwap.UserControl3"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d"

             Name="ucSupplier" Background="LightGreen"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="RadioButton" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="100" />

                <Setter Property="Foreground" Value="DarkBlue" />

            </Style>

            <Style TargetType="CheckBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="100" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="75" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="ItemsSource" Value="{Binding}" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="100" />

                <Setter Property="Width" Value="100" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

            <Style TargetType="DatePicker" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="33" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="133" />

            </Style>

        </Grid.Resources>

        <Grid.ColumnDefinitions>

            <!--nine equal Cols -->

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

            <!--nine equal Rows -->

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

        <Image Grid.ColumnSpan="3" Grid.Column="6"

               Grid.Row="1" Grid.RowSpan="3"

               Source="Images/Suppliers/imagesAP0OOHVJ.jpg"/>

        <Label Grid.ColumnSpan="4" Content="Supplier Details :" />

        <!-- above is implied / default of row & col = 0 -->

        <ComboBox Name="cbxUC3" Grid.ColumnSpan="5" Grid.Row="1"

                  Margin="0,7,0,0" Width="166"/>

        <GroupBox Header="Type &amp; Coverage :" HorizontalAlignment="Left" Height="110" Margin="7,19,0,0"

                      VerticalAlignment="Top" Width="129" Grid.ColumnSpan="5" Grid.Row="5" Grid.RowSpan="4"

                  FontWeight="Bold" Foreground="DarkBlue">

            <StackPanel Orientation="Vertical">

                <TextBlock/>

                <RadioButton x:Name="rbLocal" Content="Local :" />

                <RadioButton x:Name="rbNational" Content="National :" />

                <RadioButton x:Name="rbInternational" Content="International :" />

            </StackPanel>

        </GroupBox>

        <TextBox Name="tbxSuppliers" Grid.ColumnSpan="4" Grid.Row="2"

                 Margin="0,10,0,0" TextWrapping="Wrap"

                 Text="{Binding Mode=OneWay}" Width="133"/>

        <TextBlock Grid.Row="4" TextWrapping="Wrap"

                   Text="The information MUST be 100% correct !!" Grid.ColumnSpan="5"

                   Width="166"/>

        <DatePicker Grid.ColumnSpan="4" Grid.Column="5" Grid.Row="6"

                    DisplayDate="{Binding Mode=OneWay}"

                    Name="dtpSuppliers" />

        <CheckBox Grid.ColumnSpan="3" Content="Very Reliable :"

                  Name="chbxQuality" Grid.Row="5" Grid.Column="5"/>

        <Button Grid.ColumnSpan="2" Content="Keep" Grid.Column="6"

                Name="pbKeep" Grid.Row="8" Width="66"

                Click="pbKeep_Click" Background="LemonChiffon"/>

    </Grid>

</UserControl>

=====================================================================================

=====================================================================================

PHH - 2nd. November 2013.


Example (C#) - Better binding, Data to UCs

Example (C#) - Better binding, Data to UCs

Example (C#) - Better binding, Data to UCs

 Previous topic Next topic

Okay then folks, we have seen in the last sub-section how we may bind our User Controls (UCs) to

the Content Control CC) on a XAML/WPF form or window.

As well as swapping the UCs in an out at runtime by changing a single line of 'binding' .NET code.

Well, in this subsection we are going to study now 'best' to do data binding to our new UCs.

We need to improve upon the test / demo data binding we did previously.

In moving ahead with our skills for binding data to forms, windows, and UCs, we will be moving towards

the MVVM pattern of project/solution design.

Do NOT panic about this, MVVM is not as much of an issue or problem that some web articles make out.

Once we know what MVVM is, and how to do it from the word go, then we will get to like it, even love it ;-0)

Lets make a start ..........

What is 'View' and what is 'ViewModel' :

When we first come to MVVM we need to keep telling ourselves - that we view a form / window / screen, or

even a UserControl, and so the 'View' is just this.

The data or 'Model' that we view is called the 'ViewModel' - simply because it is structured around the Viewing

screen.

The class of object we design and define, is VERY much related to the UI elements we have on our screen.

The SIMPLE idea is that we have a property in out 'custom' class which maps (or relates) to each and every

GUI control.

So that once we instantiate and populate a ViewModel (VM) object we simply have to make one 'binding'

connection from object to screen to have 'done the job' !

This single V to VM connection is called 'loose coupling', even though it is still actually 'Data Binding'.

We need to see all of this done in our 'walk-through' exercise.

Lets move on ........................

Making a Start :

Okay guys, lets see the existing 'UserControl' which we can use as a good starting 'place'.

Let us use UC2 which was involving a 'Product' or a few of them.

Here is the designer surface we left in the last sub-section :-

====================================================

We will take this XAML script and copy it into a new (and fourth) UC in our library.

This way we can adapt and chop it about (to improve it) without spoiling what we already have working.

=====================================================

==========================================================================

===================================================================================

Ranges of type :- Box, 'Sack & Bag', and Container :

Below is the existing three 'loose couplings' to UC3 of "ProductRange" objects 1, 2 & 3.

Check how the UI elements display a varied set of values :-

===========================================================================================================================

The above changes were brought about by clicking the 'Next' button, and the code behind this

makes a cycle through the three objects, in a continuous fashion.

It would be even nicer to adapt the above class and 'UserControl' so that we can provide different

image sources as well.

I may just do that ;-0)

First of all, we need to see the outline of this new 'ViewModel' class, the one which will be used to

instantiate objects for binding (or 'loose coupling') to the 'View' (or UC) object.

Study the overall form of the collapsed version of our new VM class :-

[ .. what makes this a VM class is simply because of how it will be used, nothing else .. ]

===========================================================================

In the above image we basically have lines 16 through 84 which are the class definition itself.

The STATIC methods are just a convenience to us - so that we can have a suitably populated object

when we need to do some 'loose coupling' or data binding, later.

The event and its associated method are crucial, or vital, to the working of ViewModel with View.

Check these out :-

=========================================================================================

We need to see how we incorporate the handler method into our settings, or value assignments.

In the following image we see examples of four data types, String, Logic, DateTime, and List<T>.

Study the following carefully :-

===========================================================================================

Looking at the above details we see that we have a public Property for each and every private field,

but it does not need to be like this.

Likewise we can have some properties which send no notification - if that is what we choose to do.

I am just giving you a good working 'basic' example, for you to try, adapt, and experiment with.

Moving on ..............

What do the STATIC methods do for us ? :

Well, before we try to answer that question, let us take a close look at what one of them looks like.

Study the following carefully :-

================================================================

Notice in the above .NET code we are simply instantiating a 'ProductRange' object and then

populating all of the properties in an appropriate manner.

So the three methods PR1(), PR2(), and PR3() are just providing / returning an object of type

'ProductRange' which has had values applied to it.

Lets see how we link this up with the functioning of the 'Next' button.

What does the 'Next' button do for us ? :

These easiest way to answer this question is for us to take a careful look at what our working

.NET code does.

Check below the 'Click' event handler method - it cycles through / round the three 'loose coupling'

options in turn :-

==========================================================================

So in the lines 40,45, and 50, we make a data binding, or as we are calling it a 'loose coupling'.

In fact a loose coupling also involves some other cleaning of the code - BUT - it is a good place to start ;-0)

We would really have 'loose coupling' if we removed our .NET code from the code behind the UC and place

it in some adapted form within the ViewModel class itself. here the VM class is our 'ProductRange' class.

Lets move on a pace ......

Making the 'Binding' - at both ends :

Okay then guys, it is all very well having a View (UC) and a ViewModel ('ProductRange' object), but we need

to bring the two together in a 'Binding' !

Before we move completely over to the MVVM way of doing things, we need to add a small amount to our

.NET code, as well as a small amount to our XAML script.

Lets see what this looks like - here is what we need in XAML script :-

===============================================================================================

In the above image it is line 8 which allows binding to occur when we do 'stuff' right at the .NET code side.

Here is what we have to do in .NET code :-

================================================================

Yes, very quick, and VERY easy ;-)

Lines 8 and 40 are all it takes to put the 'Binding' in place.

However, we do need to set up our XAML script so the UI elements and controls are associated correctly

with the suitable properties on the ViewModel object.

Let us now look at two such XAML binding 'pointers' - checkout the following :-

=====================================================================================================

In the above image we see that line 84 and line 89 point to the properties of the object which is bound to

the View.

So in effect this attribute 'binding' is more of a pointer to a property than a physical link or binding / connection.

If we make 'pointers' using '{Binding Path=xyz}' and the property does not exist (or is wrongly spelled) then we

do not get errors, just nothing happens for that particular binding association.

Look at the next image detail - that below :-

======================================================================================================

Yes, we can have a 'Mode' of binding, and this is a bit of a topic in itself, but if we wish the screen to be

interactive, and the screen to also reflect code changes to attribute values, then we required 'TwoWay' binding.

However, the system is clever and applies a default, so we may have it without even asking for it.

lets move on ...........

Broadening our Horizons :

Now then guys, let us have a look at another part of our working UC screen. We will examine the 'Label's.

Study this carefully :-

========================================================================

As you can see in the highlighted section above, we can bind to one or two Label element attributes.

This works fine and we see the results below at runtime :-

===============================================================================

There is only one problem to this and that is when we get our heads up and look at what other platform

we need to write apps for - like Tablet and Phone.

Both 'Modern' apps and 'Phone8' apps do not have a 'Label' UI element available in the Toolbox. Don't

ask me why !!

So if we are to maximise our ability to copy and pasted XAML script from one platform to another, then

we would be best to forget using Labels, and try using something common to as many platforms as

possible - like the 'TextBlock' for example - that is there for all, including SilverLight 5.

In probably about a minute I have changed the XAML script for the UC2 - Product related - screen to use

'TextBlock's in place of labels - and Bingo, it works just fine.

Check this out below :-

==============================================

Yes, above we see that the TextBlocks show in place of the Labels.

Here are the changes I made - starting with the Resources section :-

============================================================================================

And in the body of the XAML script itself we see the following changes in the Tags, and 'Content' to 'Text'

attributes being changed over :-

======================================================================

That seems great, and thinking ahead even further, it would be nice to copy and paste the XAML script

directly into a new Tablet / 'Modern' style app, and only have to make a few changes to be able to get it to

work, straight-off.

I will try out this exercise of WPF to WinRT in another section, it will be an interesting and instructive exercise.

Binding an Image Source - an Improvement :

Okay then guys, lets enjoy ourselves a little, and have some fun ;-0)

Let us add some binding of the Image control on the UC (two) to a new property we specify on the

ViewModel class - this property will be named 'ImageSource', and be a string data type.

Look at how we use this in the XAML script for the Style for an Image control :-

==========================================================================================

And here is our new Image declaration with the 'Source' attribute removed because of the change to the Style

seen above :-

=================================================================

When I run the app and select the 'Blue' UC, then click through the 'Next' button cycle we see these :-

==========================================================================

Yep! we are seeing a change as we go through the various bindings.

Now then, lets see the extra parts we have added to our .NET code - check below :-

===========================================================================================

Quite simple changes as we are dealing with a 'string' data type.

We obviously need to add a line to the population code in the three STATIC methods - here is one :-

========================================================================

Enough of enjoying ourselves, time to move on.

See you in the next sub-section ................

PHH - 5th. & 6th. November 2013.


working script and code

working script and code

working script and code

 Previous topic Next topic

==================================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//------------------------------------------------------
using System.Collections;
using System.Collections.ObjectModel; //----- ObservableCollection .....
using System.ComponentModel; //----- INotifyPropertyChanged .....

namespace WpfControlLibrarySwap.SupportingClasses
{
public class ProductRange : INotifyPropertyChanged
{
//----- fields ['private' by default] -----
string _range;
Boolean _lQuality;
Boolean _lLongShelfLife;
Boolean _lGoodPrice;
Boolean _lStacksWell;
DateTime _dtIntroduced;
List<string> _aListProdItms;
string _imageSource;

//----- events -----
public event PropertyChangedEventHandler PropertyChanged;

//----- properties -----
public string ImageSource
{
get { return _imageSource; }
set { _imageSource = value; NotifyPropertyChanged("ImageSource"); }
}

public string Range
{
get{ return _range; }
set { _range = value; NotifyPropertyChanged("Range"); }
}

public Boolean lQuality
{
get{ return _lQuality; }
set { _lQuality = value; NotifyPropertyChanged("lQuality"); }
}

public Boolean lLongShelfLife
{
get { return _lLongShelfLife; }
set { _lLongShelfLife = value; NotifyPropertyChanged("lLongShelfLife"); }
}

public Boolean lGoodPrice
{
get { return _lGoodPrice; }
set { _lGoodPrice = value; NotifyPropertyChanged("lGoodPrice"); }
}

public Boolean lStacksWell
{
get { return _lStacksWell; }
set { _lStacksWell = value; NotifyPropertyChanged("lStacksWell"); }
}

public DateTime dtIntroduced
{
get { return _dtIntroduced; }
set { _dtIntroduced = value; NotifyPropertyChanged("dtIntroduced"); }
}

public List<string> aListProdItms
{
get { return _aListProdItms; }
set { _aListProdItms = value; NotifyPropertyChanged("aListProdItms"); }
}

//----- constructors -----
public ProductRange()
{
this.aListProdItms = new List<string>();
}

//----- methods -----
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//---------------------------------------------------------------------------

//----- static methods -----
public static ProductRange PR1()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Boxes :";
oPR.lGoodPrice = true;
oPR.lLongShelfLife = true;
oPR.lQuality = false;
oPR.lStacksWell = false;
oPR.ImageSource = "Images/Products/imagesM6EIIJJQ.jpg";
//------------------------
oPR.dtIntroduced = new DateTime(2005,05,17);
//-------------------------------------------
oPR.aListProdItms.Add("Short, high sides");
oPR.aListProdItms.Add("Narrow, low sides");
oPR.aListProdItms.Add("Short and Narrow");
oPR.aListProdItms.Add("Long and Wide");
oPR.aListProdItms.Add("Wide, high sides");
return oPR;
}
public static ProductRange PR2()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Containers :";
oPR.lGoodPrice = false;
oPR.lLongShelfLife = true;
oPR.lQuality = true;
oPR.lStacksWell = false;
oPR.ImageSource = "Images/Products/imagesMQHEDGWJ.jpg";
//------------------------
oPR.dtIntroduced = new DateTime(2007,07,27);
//-------------------------------------------
oPR.aListProdItms.Add("Short, hard tops");
oPR.aListProdItms.Add("Narrow, soft sides");
oPR.aListProdItms.Add("Hard all round");
oPR.aListProdItms.Add("Open top");
oPR.aListProdItms.Add("Closed top");
return oPR;
}
public static ProductRange PR3()
{
ProductRange oPR = new ProductRange();
oPR.Range = "Sacks & Bags :";
oPR.lGoodPrice = false;
oPR.lLongShelfLife = false;
oPR.lQuality = false;
oPR.lStacksWell = true;
oPR.ImageSource = "Images/Products/VWcar.png";
//------------------------
oPR.dtIntroduced = new DateTime(2003,09,22);
//-------------------------------------------
oPR.aListProdItms.Add("Deep & Wide");
oPR.aListProdItms.Add("Wide but short");
oPR.aListProdItms.Add("Tops narrow");
oPR.aListProdItms.Add("Tops very Wide");
oPR.aListProdItms.Add("One inside another");
return oPR;
}

}
}
==================================================================================
<UserControl x:Class="WpfControlLibrarySwap.ProductUC4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DesignHeight="300" d:DesignWidth="300" mc:Ignorable="d"
Name="ucProduct4" Background="SkyBlue"
DataContext="{Binding}">
<Grid >
<Grid.Resources>
<Style TargetType="CheckBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="110" />
</Style>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="75" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="110" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="ComboBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="ItemsSource" Value="{Binding}" />
</Style>
<Style TargetType="Image" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="100" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stretch" Value="Fill" />
<Setter Property="Source" Value="{Binding Path=ImageSource}" />
</Style>
<Style TargetType="DatePicker" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="33" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="133" />
</Style>
</Grid.Resources>

<Grid.ColumnDefinitions>
<!--nine equal Cols -->
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!--nine equal Rows -->
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>

<Image Grid.ColumnSpan="3" Grid.Column="6"
Grid.Row="1" Grid.RowSpan="3" />

<TextBlock Grid.ColumnSpan="4" Text="Products in Range :"
Margin="0,0,0,0" Grid.Column="1"/>

<TextBlock Grid.ColumnSpan="5" Text="Date Introduced :"
Margin="0,7,0,0" Grid.Row="6" />

<TextBlock Grid.ColumnSpan="3" Grid.Column="6"
Name="lbRange" Text="{Binding Path=Range}" />

<ComboBox Name="cbxUC2" Grid.ColumnSpan="5" Grid.Row="1"
Grid.Column="1" Width="150" ItemsSource="{Binding Path=aListProdItms}"
SelectedIndex="0"/>

<CheckBox Name="chbxQuality" Content="Quality :" Grid.Column="1"
Margin="10,8,0,0" Grid.Row="3" Grid.ColumnSpan="4"
IsChecked="{Binding Path=lQuality}"/>

<CheckBox Name="chbxGoodPrice" Content="Good Price :" Grid.Column="1"
Margin="10,7,0,0" Grid.Row="4" Grid.ColumnSpan="4"
IsChecked="{Binding Path=lGoodPrice}"/>

<CheckBox Name="chbxLongShelfLife" Content="Long Shelf Life :" Grid.Column="1"
Margin="10,7,0,0" Grid.Row="2" Grid.ColumnSpan="4"
IsChecked="{Binding Path=lLongShelfLife}"/>

<CheckBox Grid.ColumnSpan="4" Content="Stacks Well :" Grid.Column="1"
Name="chbxStacksWell" Margin="10,8,0,0" Grid.Row="5"
IsChecked="{Binding Path=lStacksWell}"/>

<Button Name="pbNext" Grid.ColumnSpan="3" Content="Next"
Grid.Column="6" Grid.Row="8" Width="90"
Background="GreenYellow" Click="pbNext_Click" Margin="10,7,0,0" RenderTransformOrigin="0.378,-0.5" />

<DatePicker Name="dtpProduct" Grid.Row="7"
Grid.ColumnSpan="6" SelectedDate="{Binding Path=dtIntroduced, Mode=TwoWay}"
Width="167" Margin="10,0,0,0" />

</Grid>
</UserControl>

==================================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//---------------------------------
using WpfControlLibrarySwap.SupportingClasses;

namespace WpfControlLibrarySwap
{
public partial class ProductUC4 : UserControl
{
private int nCount = 0;

public ProductUC4()
{
InitializeComponent();
}

private void pbNext_Click(object sender, RoutedEventArgs e)
{
this.nCount += 1;
if (this.nCount > 3 || this.nCount < 1)
{
this.nCount = 1;
}
//--------------------------------------
if (this.nCount == 1)
{
ProductRange oPR = ProductRange.PR1();
this.ucProduct4.DataContext = oPR;
}
if (this.nCount == 2)
{
ProductRange oPR = ProductRange.PR2();
this.ucProduct4.DataContext = oPR;
}
if (this.nCount == 3)
{
ProductRange oPR = ProductRange.PR3();
this.ucProduct4.DataContext = oPR;
}
this.cbxUC2.SelectedIndex = 0;
return;
}
}
}

==================================================================================

==================================================================================

==================================================================================

==================================================================================

==================================================================================

==================================================================================

PHH - 5th. & 6th.November 2013.


Example three

Example three

Example three

 Previous topic Next topic

PHH - 21st. October 2013.


Example four

Example four

Example four

 Previous topic Next topic

PHH - 21st. October 2013.


Example (C#) - MVVMLight for our 3 UC project

Example (C#) - MVVMLight for our 3 UC project

Example (C#) - MVVMLight for our 3 UC project

 Previous topic Next topic

This sub-section is based very closely on the excellent presentation I saw only a few days ago at

our "Visual Objects User Group" meeting in Bristol, England.

Nick Friend did a two hour session for all us local guys, during which time he went right through a small

project / app, from start to finish. Showing us how to integrate the best basic practises of the MVVM 'pattern'

of development, into our own coding and overall application design.

He used WPF technology, as we will here. He also used C# as we will in this sub-section.

However, there is no apparent reason why we can use the GalaSoft assembles for 'MVVMLight' with Vulcan.NET

3.0 or that we can't use the same skill set (and much of the code & script also) to create Tablet and Phone apps.

Tablet apps are using WinRT, and Smart-phone apps use Windows Phone 8 O/S.

What we are going to try to do :

To put it quite simply, the "User Control" app we developed, in the first two subsections of this main section, will

be completely re-written using the 'pattern' and style of approach that Nick demonstrated to us. He used the

'GalaSoft' offering of 'MVVMLight' as the base assemblies on which to build the solution.

There are other variations of MVVM support assembles, the other MAJOR player is 'Prism' from Microsoft.

In our attempt to apply the MVVM 'pattern' to our 3UC demo app, we will try to make each part of our solution

as independent of any other part, as possible. We are trying to remove ALL dependencies, so that the parts

of the project / solution can be changed or replaced, without need to worry about other parts.

If we get this separation right then we should have what is called 'loose coupling', and this will be VERY loose indeed !

Earlier, in the first two subsections on the 3UC demo app., we mention 'moving towards' looser coupling, and so we

hope to see the ultimate in loose coupling, if we get things a-okay.

Basic "Things" to Remember :

Number One :

At one level of 'getting things right' as far as MVVM is concerned, we should see the complete absence of event

handler methods in the 'code behind' any windows, screen, and user control.

Let us take a look at one of Nick's code files to see how simple it ought to be - check this out :-

==================================================================

The screen, or UI, looks like the following in the XAML Designer :-

===================================================

And if we now shift our attention to the XAML script we need to see that no event attributes have been

used, and therefore there are no references to event 'handler' methods.

If we look in detail at one of the Buttons, we see no 'Click' event used or defined, and instead the 'Command'

attribute being used - check below :-

===============================================================================================================

In the above script line 36 means that the 'SaveCityCommand' will be used / run when the Button is clicked.

In this small example we have no other 'event replacement' examples - more on that in a moment.

However, we do need to see how the Text attribute is bound so that we get changes at both ends being reflected in

both the data properties of the bound ViewModel object, as well as the trigger being defined - the UST (UpdateSourceTrigger)

can be a few things - commonest is property change, or indeed lost of focus.

Check out the following to refresh our memories on data binding :-

=================================================================================================================================

Lets move on a pace .....................

'Commands' - where and "where not" !? :

Okay folks, we need to realise that only a few UI elements / controls have a 'Command' attribute. The fast majority

of the Tools in the Toolbox do not.

Examples of command sources are 'MenuItem', 'Button' and 'KeyGesture' - so basically for everything else, and much

that we will require, we need to make the connection / mapping ourselves.

So what do we do when we have no 'Command' to use ?

We can get a good idea by studying some of Nick's script. Below is definition for one single 'interaction' for the

DataGrid control - the one which shows the city details - note lines 50 through 52 link the MouseDoubleClick event

with the command called 'EditCommand' :-

=======================================================================================================

Although we have defined only one mapping for 'Event to Command' on our Datagrid, we could have added

more into the 'Triggers' collection.

Here is another addition I just made :-

=========================================================================================

Notice that in this above code we are referring to ' i ' and this is a shorthand for a fuller namespace

as can be seen in the following image :-

================================================================================================================================

[ .. We will get to understand more about the other 'header' lines of script are, as we gradually develop

our new app.

for the moment notice that the 'References' pane needs this included as well - check below .. ]

======================================================

Moving on ..........

However, although the app compiles and runs, I have not as yet created the necessary code for the

'MoveCommand'.

Although we will deal with creating 'Command's later you may like to see what I added to support our

new XAML script addition.

Check this out carefully :-

=========================================================================

In the above image the lines 26, 33 and 69-72 have been added by me for this exercise.

So we have added an empty method - or 'blank stub' method - which 'maps' though to the name of

the Command used in our extra XAML script.

Having studied all of the above details, we are now in a much better position to move on to start our

own application.

Remember this as we 'go along' :

I will use the abbreviation 'MVL' to stand for 'MVVMLight'.

We need GUI screens, and each of these screens, or 'View's, needs a matching 'ViewModel'.

The 'VM' is a code class and should ideally not know about its data, or 'Model.

Views and VMs usually map exactly 'one-to-one' - element attribute to object property.

So each 'VM' needs a 'Model - once again as loosely coupled as possible - this may be best done

with an 'Interface'.

Models usually get their data from a 'back-end' data source, however, for the purpose of this 'MVL'

exercise we will simplify our test/demo data sources by using STATIC methods.

We are trying our very best to minimise, or eliminate, any dependency from one 'part' to another, of

our application solution.

Working apps can be MVVM to a greater or lesser degree. We try to make it 'greater' whenever possible,

and wherever it it makes coding and design sense.

Having a 'Controller' class and using it as an 'Executive' to our solution / project makes all the above more

possible to implement.

Lets move on and do some creation ..................

PHH - 9th. & 10th. November 2013.


An 'Overview' - to explain thing simply !

An 'Overview' - to explain thing simply !

 Previous topic Next topic

An 'Overview' - to explain thing simply !

 Previous topic Next topic

This is the basic 'shape' of our sample example for MVL.

The App 'launcher' code/script needs a 'Controller' to run.

The non-GUI 'Controller' then instantiates and displays a start (first) screen.

This screen is a 'View' and a 'ViewModel' (VM) is loosely bound to the 'View'.

V & VM map very closely - 'one to one'.

Although the VM is a coded class it does NOT have data values and data collections.

The data is 'injected' into the VM by the developer supplying a Model object as input

to the constructor of the VM.

The Model object has data and also gathers it from elsewhere.

To help get the Model injection correct into the VM instantiation, a specially designed

interface is made and used.

Study this carefully :-

-------------------------------------------------------------------------------------------------------------

App - launcher - (code)

-------------------------------------------------------------------------------------------------------------

*** Controller *** - (code) - instantiates a View

-------------------------------------------------------------------------------------------------------------

View - GUI screen - script layout & binding info. UI elements to properties

....... interactivity bound to VM via Command attributes

-------------------------------------------------------------------------------------------------------------

ViewModel - (code, no data) - all properties for binding, as set by the View

................ and all interactivity coded for the bound commands

-------------------------------------------------------------------------------------------------------------

Model (data values and items - code) - injected into 'VM' via the Constructor

-------------------------------------------------------------------------------------------------------------

Data Source - used to populate the Model - disk to RAM

-------------------------------------------------------------------------------------------------------------

With the exception of the Controller, each 'layer' only knows of the next layer 'down'.

So 'View' has no knowledge of the Model.

The ViewModel has no knowledge of the Data Source.

The Controller plays an "executive" role and does a lot - receiving and issuing messages.

The 'messaging' system of the Controller makes it all possible - MVVM that is.

PHH - 13th. November 2013.


Setting up a suitable new Project / Solution

Setting up a suitable new Project / Solution

Setting up a suitable new Project / Solution

 Previous topic Next topic

Okay guys, lets make a new and a clean start - open VS2012 and close any open project or

file - just close all 'things' !

Now we are going to make a new Project (Solution) using the available Templates - checkout below :-

===========================================================================================

==============================================================================================================

==========================================================

===================================================

==============================================

=======================================================

Using TFS - for Source Control :

================================================

We need to carry out our first 'Check-In' for the source control, and the

TFS (Team Foundation Server) - check below :-

=============================================

See above how the small icons, or symbols, have changed after making the first 'Check-In'.

Moving on ................

In the next sub-section we need to insert our new 'Controller' as a layer of 'action', one above the

main (or shell) screen.

So the app launch start with the 'Controller and not the 'MainWindow'.

We will then see that we can access and use the 'Controller' as an "executive" from anywhere in

the body of the application.

See you in the next sub-section ..............

PHH - 10th. November 2013.


Creating our 'Start-up' Screen and App launcher

Creating our 'Start-up' Screen and App launcher

Creating our 'Start-up' Screen and App launcher

 Previous topic Next topic

========================================

Standard Main WPF Window App XAML script :

This is what we see for a standard use of the WPF application 'Template' :-

============================================================================================

However, if we make changes on just one line (numbered 4) to the following :-

====================================================================================================

Then this above XAML script allows us to start into and exist from the Controller itself, not the GUI screen.

Now we need to see the .NET code which goes with the 'App.xaml' file - check thoroughly below :-

====================================================================================

The above code and script makes the Controller run before it itself, launches the start screen.

Before we look at the details of the Controller, and how it launches the 'Start-up' screen, we need

to see proof that we have a running application.

Lets move on a little ...........

Making our 'Start-Up' Screen :

Let us see the newly structured MVL version of our three UC swapping screen when the app is run :-

========================================================================

This looks much like it did in the previous eNotes section - however, the Task Manager has

other information to show us that it is our new app - check this out below :-

=======================================================================================

As the highlight row section shows us, the name of the app is "WpfMVLstart".

If we now examine the SE pane we see that the 'MainWindow' has been removed, or deleted.

Now our start-up screen is within the folder named 'OurViews', when in fact our other three

'UserControl' screens will be placed.

======================================

It would appear that the form and structure of the solution in our SE pane is more like what

it should be for a working MVL application.

Let us now take some time to study the details of the XAML script for the 'Start-up' screen.

Check out these details carefully :-

======================================================================================================================

Be aware that the name attributes for many items are still remaining in our script, however, we will not be using these

in the code behind, in the non-MVVM manner we did previously.

For many UI elements the name simply serves as a reminder to me when I am working on designing the script sections.

As we get used to designing Views for MVL generally, I suspect that the names will get used much less.

Now then, the easy bit - checking out the basic XAML script, but stuff that is not involved in binding. Check this out :-

==============================================================================

Making things 'Happen' :

You will notice that in XAML script lines 61, 63 & 65 shown above, that the event attributes are now missing, no more

'Click' events with associated method handlers.

So at the moment we will not get any response when we click a Button on our start-up screen.

Let us see how Nick deals with this in his example 'shell' screen - check this out below :-

=========================================================================================================================================

Yes, we see that Nick has three Buttons, and for each shown above and below, we notice that

he is using the 'Command' attribute, with a binding to a named method 'handler'. We will look at

these handlers a little later.

Here is the graphical designer surface with Buttons showing :-

==========================

Moving on a little .................

Remember that the code behind the View, or GUI screen, has to be as 'empty' and as simple as possible.

This means in this case that the methods to handle the Command binding for the three Buttons needs to be

placed in the ViewModel (VM) code itself. Remember the VM is bound to the View.

Let us see what Nick's example shows us, and then how we copy the corrects bits for our example.

Check out the following - from Nick's example :-

===============================================================

The above collapsed coding of the VM class shows three distinct regions, extra to the Constructor itself.

It would seem likely that we need to look into the regions for Commands and Methods.

Lets do this, maybe it would be best to checkout the Methods first - see below :-

================================================================================================================================

So in the above image we see a single line of code for each 'handler' method.

When we first make ours we can either leave them empty or throw up a message box.

Now we need to move on to the mapping of Method to Command .....................

The 'Command' region - Mapping and Registration :

Okay folks, we need to realise that there are two things we need to do when it comes to 'Commands'.

We need to map or associate a Command with a Method to handle it, as well as also register, or

initialise, the 'RelayCommand' objects with the 'MVL' system.

We can tell that 'RelayCommand' is an 'MVL' type by hovering the mouse over the code, and IntelliSense

reports back to us - check this out below :-

=================================================================================================

And if we now open and study Nick's whole region for Commands, we see the following details :-

========================================================================================

So the guys, we seem to be a position which allows us to go off and make changes to our existing

XAML script, and then VM code.

Before we add script and code details, we need a fourth Button as seen at runtime - below :-

========================================================================

Above we have added the lower Button to close the shell screen - it looks better in real life ;-0)

Lets move on to text changes - XAML and code ......................

First let us see what XAML script we have to start with, before we make the necessary changes :-

==============================================================================================================

Note that for the new 'Button' element I have not given it a 'Name' attribute value - no need !

Secondly, let us add in our 'Command' script text to our View - check this out below :-

=====================================================================================================================

[ .. CARE above, to add the 'Command' as a convention to the name of the actual command object to be in the VM code .. ]

All we have done is add lines 61, 64, 67, and 70 - with a suitably structure 'Command' attribute and value pair.

The 'Path' has a value which I created, or made up, to suit the action I wish to take place.

So as yet 'DisplayCustomers' and the other three similar values, do not exist anywhere else.

If our XAML editor / compiler is consistent we ought to be able to leave out the 'Path=' in the alternative

syntax shown below :-

====================================================================================================================

[ .. and it works as it should ! .. ]

Notice that line 70 now looks different !

Lets move on to make some suitable methods .................

Making the Methods :

Remember that any and all coding goes in the ViewModel (VM) file section.

Here is a bunch of empty 'stub' methods :-

=================================================

Although the above will compile and work, it is best to try using a simple 'MessageBox' approach until

you get more experience with MVL.

So here is another alternative - check below :-

==============================================================================================

This time, when we compile and run the application we see a variety of message box outputs, but

no other action as yet.

Here are a couple of output results :-

========================================================================================================

The above works well, but if we wish to have an 'Action' other than a static message displayed, then we need

to do something like the following - checkout lines 69 & 70 below :-

======================================================================================

The above code works but is dependent upon some other code we are yet to look at in detail.

First here is the runtime display :-

===========================================

And here is a preview of the code we need to study and further develop - it all has to do with

the Controller, and messaging etc., etc..

Check this out as a final part of this section :-

===========================================================================================

Notice that in the above image we have not tested for different values of the input 'msg' and in

fact any value other than 'Close' would also shut down our application.

This part of the Controller will be studied in the next sub-section, first - before we leave this section -

we need to study the Mapping and Registering code .................

Mapping and Registering :

To make our MVL project work as we would wish it to, the Command specifications in the XAML script

need to be 'mapped' or associated with the handler methods themselves.

This is done through the use of 'RelayCommand' objects, and these effectively register the mapping of

the two. See below for how this is done in the VM code file :-

===================================================================================

In the above code we can see that the names of the 'RelayCommand' (RC) objects are exactly those used

in the XAML script of the 'Command' binding.

By convention developers add the text string 'Command' to the name they wish to use to describe its

function, or action.

The public 'RC' objects must have the same name exactly as those used in the XAML binding.

However, when we get to making the association of the 'RC' object with a handler method, we can in principal

use any method name we choose.

But, to keep the developer 'sane' it is probably a good idea to keep the names similar, such that the ones

shown here have method names the same as the RC names, but with the 'Command' dropped from the RHS of

these names.

Here is what I have now, at this stage of my application development :-

=========================================================================================================================

[ .. so above, line 68 "says" close the shell screen and no data is involved .. ]

The above code represents the four possible action paths available from my four Button 'switching' input.

These will get 'fleshed' out when we know exactly what we need to do - to bind different 'UserControl's.

Time to move on, lets go and study the details required for a fully working Controller, and messaging system.

See you in the next sub-section ....................

PHH - 10th. & 11th. November 2013.


Making a Start - Initial Design & 'Controller'

Making a Start - Initial Design & 'Controller'

Making a Start - Initial Design & 'Controller'

 Previous topic Next topic

=============================================

====================================================================================

=========================================

Checking things so far - 'Build and Run' :

================================================================

Moving on Further - the 'Controller' and 'Messaging' :

Let us start by trying to simplify things, so that we have a good understanding in our heads of what

messaging via the controller is all about.

Think of our application as a set of Views and related ViewModels. The interactive View screen allow

the user to do a job, or indeed many jobs.

The 'Controller' is a working structure which can be thought of as being over and above the UI screens,

and indeed the application itself.

Checkout the structure of the SE pane to see where the Controller resides :-

=======================================================================================

Both the 'Controller' and the 'ControllerMessage' reside in this folder called ''OurController',

and as you can see above in the same code file too - named 'OurController.cs'.

Lets move on ....................

The various parts of the application communicate with the Controller via a set of messages. The messages

are actually quite simple, and in our case are 'enums' which represent View type and actions, as well as

Data action and a data item ID.

Please also realise that the content of these messages is structured by us, the developer, as the 'ControllerMessage'

class is defined by ourselves.

It is now time to study the format of the 'ControllerMessage' which Nick has fashioned for us. Yes, we may as well use

what Nick provided in his working MVL sample, at least till we get enough experience to be able to add to it or change

it in other ways.

Checkout the following very carefully :-

=======================================================================================================================

[ .. note that the fourth parameter is just a 'nullable' numeric, an integer .. ]

So now that we have an important class using our 'enum's, we had better take a look at what Nick has

designed into these for our immediate use.

The 'enums' are defined in the folder shown open in the image below :-

===========================================

And although we have not as yet got any supporting classes for our application, we do

have three 'enum's which we will use at the next stage of our application - when we come

to bind a UC from our bunch of three.

Checkout the following 'enum' details :-

=============================================

Now then folks, before we move on, you need to realise that the above details are

not written in stone, they were selected and defined by Nick as he thought them useful for

his data related Vs & VMs.

As we get into more, and different, apps we may well need to change and adapt this above approach.

Probably at first just a few line details.Bets to go 'softly - softly'.

Okay then guys, lets move on, we now have messages and their required enums to indicate what is

required by the message.

To REALLY simplify things, we need to understand that any message we send to the Controller using

the messages as seen above, are really just four integer values - these represent VIEW - type and action,

as well as DATA - action and ID.

Nothing less, nothing more. When an ID for data does not make sense we then send 'NULL'.

Each of the other three input parameters MUST have an existing enum 'value'.

Moving on ..............................

What needs Changing immediately ? :

Okay then any eagle eyed folks amongst you, there is one enum which drastically needs to be

changed and adapted, because it is VERY much related to the purpose and functionality of our application.

Check this out to see if you can work out what we need changing :-

========================================

Yep! that is right, we only have a Shell screen from the five named ones above.

Nick in his sample MVL app had Views for Person and City, and with two flavours of each, List and Edit.

If you have followed the' swapping 3UC' app development previously, you will know that we have Customers,

Products and Suppliers to select and choose from.

So let us make a few changes for ourselves - check below :-

======================================

Remember that 'Shell' is our start or launch screen, and the three others are the 'UserControl' screens which

get bound to the 'ContentControl' of the Shell screen.

Improving / updating our messages :

Okay then folks, now we have some suitable 'enum' values we can add suitable messages to go along with

the Command method actions and handlers - check these out below :-

[ .. now we can use some of these new 'enum' values .. ]

===============================================================================================================================

Notice in the above .NET code that we are opening each of the three different UserControls, and that the 'ViewType'

new values are being used.

Now we can consider the other end of things, and see where the sent messages are processed

and hopefully understood ;-)

===================================================================================================================

At the moment, the best I can offer is a suitable message box output as seen below :-

==========================================================================================================

Now its time for a break, its been a long day, and we can get stuck into providing the 3 Views of type UC in

the morning when we are all fresh ;-0))

See you in the morning!

Completing the Task / Job :

Okay then folks, in order to be able to complete the Controller (well nearly complete) we first need to

make sure we have created our 'View's and our 'ViewModel's (VMs).

Once we get our Controller to handle the three user control View objects it should collapse to look

something like the following :-

=====================================================

Notice we have the 'ControllerMessage' class as well - at the bottom of the above image.

So lets check that I have done my homework correctly, a little while ago.

Below is show the View folder and the VM folder - each has three new entries - check this out :-

=======================================================================================

Now then, to be perfectly honest with you, the Vs & VMs are just VERY basic frameworks at the moment.

They have enough detail and content such that we can add them into the Controller for creating the logic

and code for the 'Shell' window to become active as far as the swapping in and out of the UserControls is

concerned.

We 'add to', or 'beef up', the data items and supporting Models later, in a sub-section dedicated to that

particular task / job.

For the moment lets focus on the Controller and getting the right code in place.

Here is a more expanded view of the Controller, with the four regions :- Fields, Properties, Constructors,

and Methods (I am not sure we will use many properties !) :-

=================================================================================================

Well, not too complex it would seem.

Let us now study an import two methods, even though they are small. These are shown

below and are 'Initialize' and 'Start'.

============================================================

From Nick's example I have decided to move the shell instantiation from 'Start' to 'Initialize'.

And now we need to see the working code for the 'MessageProcessor', however, I do wish to replace the

nested IF statements - I do not like coding with such a structure.

Lets see what we have now, and what works :-

=======================================================================================================

After you study the above .NET code you need to check the following, as it is the runtime output :-

===============================================================================================================================================================

Now in the running app we can use the mouse to click the Buttons and the ContentControl (CC)

then shows different colours - red, green and blue.

This happens with no user events being declared or used, just Commands, that is all.

Let us try to do some work on the code structure within the Controller - so that it looks cleaner

and a bit tidier too.

Alternative way to Structure the Controller :

Instead of instantiating the user controls, or Views and ViewModels, on demand at the time they

are required by interactive screen input, we can do it when the app is launched, and the Controller

used for the first time.

We need to add private fields for each of our three new V & VM pairs - check this out :-

=========================================================

And now we need to study the three extra instantiations - check below CAREFULLY ! :-

=======================================================

So with the above code out of the way in the initialising method we can simplify our code to look like

that see in the following image - check this out :-

======================================================================================================

So we now have one line of code for most of the Action/Type switching.

And to build and run to check that all is still OK with our script and code we see this :-

Yep! our application still builds and runs as it should.

Since we still have a 'runner' we need to think of our Source Control, and use TFS to save what we

have working ..............

Use Version Control - 'TFS' - to save the fully working App :

Highlight the solution node and use the context menu to 'Check-In' all of the code.

Here is what I have after doing a 'Check-In' :- [ .. note all red checks (ticks) have gone .. ]

================================================

Lets move on and do something useful.

Now then, my favourite part, getting rid of those nested 'IF's - check this out below :-

==========================================================================================================

The above is my first attempt at doing a code tidy with 'switch'. And although it works fine I would like to

improve on it.

There is a useful web link shown below - I consulted it for help and advice :-

http://msdn.microsoft.com/en-us/library/aa664749(v=vs.71).aspx

If we now try to put all of our case 'switches' into one structure, we can do this :-

==========================================================================================================

The above coding does need some explanation, as to how the 'case' value is generated, and why.

However, we also need to keep in mind that we can split things up a bit by having more than one

'ControllerMessge' class.

Nick suggested having possibly 'ControllerOpenMessage' and 'ControllerCloseMessage' etc..

We need to keep this in mind for another time, and app, if our nesting or switching gets a little out of

hand then we can go for splitting the ControllerMessage classes to handle different 'chunks' of messages.

Now then, back to explaining why right above (in the last image) we use ' 10 ' as a multiplier on the ViewAction

enums.

Remember (in this app) our enum values are just the first few integers starting from zero. So we can effectively

give different place values to each in turn when we combine them.

As an example, " Close and Shell " have values of 1 and 3 - but when we apply our shifting technique we get

a final value of 10 + 3 which is '13'.

So using the same logic and algorithm we have "Open/Customers" is '01' ans "Close.Suppliers" is '12'.

Just in case any of you think that we can get around this by using a method like seen below, forget it, the

compiler says we MUST have a constant value and not a variable in our 'case' definition.

====================================================================================

There is plenty for us to explore later, in other projects, for now lets make do with our working code seen

two images above.

Lets move on and get our dat via Models into our VMs and hence our matching Views.

See you in the next sub-section .......................

PHH - 10th. & 11th. & 12th. November 2013.


Designing and Creating our 'View's

Designing and Creating our 'View's

Designing and Creating our 'View's

 Previous topic Next topic

Okay then guys, lets get to it - a new day and a fresh mind ;-0)

At the moment we have our SE pane looking like the following image :-

=========================================

We need to add three more Views which are based on 'UserControl'.

If we right click on the node item called 'OurViews' we get a suitable context menu as

seen below :-

===================================================================================

By making the above selection we see the 'Add New Item' dialog screen - seen below :-

================================================================================================

Note the name I input was 'ucCustomerView', as well as the ' .xaml' extension.

Repeat this for both 'ucProductView' and 'ucSupplierView', and you will then have a SE pane looking like

the following :-

===============================================

If we now take our last entry for 'Supplier' as an example, we can explore the two files which were auto-generated

by the Template selection.

Check this out as the 'stub' XAML script file :-

==========================================================================================

And as well as the XAML script file we get a .NET code file as seen below :-

============================================================

So then, with a pair of files for each of the three UserConctrols looking similar to those above,

we can simply make sure they are coloured according to our previous colour scheme, and then

use these with the completion phase of our Controller.

Here is just the green 'Supplier' user control (UC) - check below :-

==============================================================================

That seems just fine.

Moving on ............................

Since Views and ViewModels (VMs) go together like a hand and glove, we need to move on to the

next sub-section where we will see how to create suitable VMs for the above Views.

See you in the next sub-section .............

PHH - 12th. November 2013.


Making the 'Product' View from scratch

Making the 'Product' View from scratch

Making the 'Product' View from scratch

 Previous topic Next topic

Okay then guys, with what we know so far, let us try to make a usable 'View' right from the

Template selection in VS 2012.

The template I will use for this example is the 'UserControl' template for WPF in C#.

Apart from a background colour being added, this is what you should see for your XAML script

after selecting this template :-

=====================================================================================================

Yes, as you can see above, we have no extra lines of script to support MVL from Galasoft, and also no

UI elements, or controls, placed on the designer surface from the Toolbox - or by direct typing.

Let us assume that we will make a reasonably interactive screen, and so will need access to all the

possible View facilities from MVL.

Here are the first couple of extra script line we need to add into the UC attribute list / section :-

=======================================================================================================================================

Notice in the above image, that IntelliSense provides us with options from the list of already entered VMs.

Here is what we currently have in our SE pane structure, and entries :-

=======================================

Once we select correctly we see that the wavy line disappears, like shown below :-

=============================================================================================================================

However, we still need a further two lines of script - check this out below :-

=====================================================================================================================

Check to see that the assemblies used (referred to) in lines 10 and 11 are actually

in the References section of our SE pane.

Here is what we should have (if not add them) :-

===========================================

==============================================================================================================================

======================================================================================

Now to check that we have not done anything wrong, or silly, do a Build and Run.

Here is what I get after clicking the 'Product' button :-

==============================================================

Yep! - I know, not a lot showing, a good job for the blue colour ;-0)

==========================================================

Now add a couple more rows and columns to make a total of eleven each, then

collapse the script lines - here is what we get :-

=============================================================================

And now lets copy and paste some Resources for some standard controls, just so we can then

simplify and 'clean' our XAML script.

Check this out below :-

=================================================================================

In the above image we see one expanded control Style section, all of the others are similar.

Make sure that any lines in the Styles subsections are removed if they involve 'Binding'.

Check the 'ComboBox', this may have copied over from the 'Suppliers' View.

Collapse the Resources and we should have this shown below :-

===================================================================================

Let move on ...................

Adding some Controls :

Well know, this is the place where we need to be both imaginative, and creative ;-0)

We need to think through carefully what the user is going to use the screen for, and what the

functionality should be, in some detail.

For our current task - making a screen for 'Product's - we have quite an easy job really.

List us have a drop list for the list of product items, and when any item is selected, it will then

have its properties displayed in a TextBlock and on an Image control.

We will have a title / header TextBlock, and a Button to clear any previous list selection.

That completes the design outline.

Lets now make a move, and add a Title 'TextBlock' - check this out :-

===================================================================================================

After dragging the handles to snap to the grid lines, you may wish to return to the XAML script of the Resources

section and edit the values there - just so we can keep the body of our XAML script clean and clear.

Here is what I am doing :-

==================================================================================

Until we get a suitable VM and make some bindings, lets give the Text attribute a fixed value :-

============================================================================================

Now follow the following image script to add a few more controls - check this out carefully :-

==========================================================================================

While I dragged tools from the Toolbox, and then adjusted their handles, I also made a few changes

to the values in the relevant Styles in the Resources section.

I have added this updated script into the 'working child folder.

And just for a break, and to motivate ourselves a little ;-) do a build and run to see this shown below :-

==============================================

Not fancy enough for you ? then lets add an image source just till we can do the binding properly later.

How about this ? :-

======================================================================================================

And making a final addition before going to the VM, we need to set up the script so that we can use a

Command in place of an event. We need to track the change of drop list selection - check this out :-

=======================================================================================================

*** CARE *** please be warned that to get the wavy 'error' lines to disappear from the XAML editor, I needed

to Rebuild, but the save and reload VS with the same project - that seemed to clear my issues and all works

as it should at the moment.

I don't often get things like this, but I certainly did while trying to get the XAML editor to recognise the ' i ' for

'Interaction'.

========================================

This now means that in the VM we need to create a link from 'SelectionChangedCommand' as a RelayCommand

type to a handler method - hopefully we can call this 'SelectionChanged' - we will have to see.

Okay then folks, whereto next ?

It seems to me that we need to make a suitable, and supporting ViewModel. Once we have its supporting

properties we can then set-up the bindings - mapping display to the data behind.

I will now go off and make this VM, and will record my actions in the next sub-section from here.

You can either continue reading and following this section, or go off and checkout the one I am

referring to.

See you soon ........................

Applying the ViewModel :

Clearing the Index - "action to our Button" :

Finally, we need to add some interaction, or behaviour, to our push button.

Here is what we are going to start with - check below :-

=========================================================================

If we start with a selected item from the bound collection, and its full details text display,

we need to reset these both to an 'unset' pair of values.

Here is what we end up with once we get our script and coding correct :-

=================================================================================

So the guys, where do we start ?

How about adding the necessary script to the XAML fro the Button - check out line 147 :-

=================================================================================================

So we will need to make a suitable Command in our VM code - here is a start :-

==========================================================================================

Remember that the 'Command' text at the right hand end of the name is 'convention' - we don't have

to add it but it is a good idea as most other folks should do the same.

In the image below we see that line 114 links (associates) the Command with the method called 'ClearIndex'

and the code also registers this pairing in our system :-

==========================================================================================

Now we need a method to call and run when we use the 'Command' from the push of the Button.

Check this out :-

=============================================================

Yes, in the above code we need to do two things - reset the index, and also clear, or reset,

the text being displayed.

Note that it was not enough to just reset the index - this just left the current text displayed.

Now then, we need to see the code for the new property called 'OurIndex', as well as the

private field.

Here is the property - and it is similar to all the others in structure and form - check this :-

==============================================================

And now we can see in the next image the private field and the initializing code when the

'UserControl' is first instantiated - the View along with the ViewModel.

Study this carefully :-

===========================================================================

And finally, we now need to see how we bind the 'OurIndex' property to the ComboBox itself.

We will assume that the converter within XAML will do its job as expected ;-0)

Check this XAML script :-

======================================================================================================

And that is the end of the story as far as the Button click being a Command which runs a method.

After some practise it all makes sense, and just feels right.

Let us now go and study some other aspect of MVL - and MVVM generally.

How about linking a "mouse button down" on the Image control, so that it changes to another image.

We can make the action a 'cycle' rather than a toggle.

See you in the next section .......................

PHH - 15th. & 16th. & 17th. November 2013.


working XAML script and .NET code

working XAML script and .NET code

working XAML script and .NET code

 Previous topic Next topic

====================================================================================

<UserControl x:Class="WpfMVLstart.OurViewModels.ucProductView"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:local="clr-namespace:WpfMVLstart.OurViewModels"

             d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ProductViewModel}}"

             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

             xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"

             mc:Ignorable="d" Background="SkyBlue"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="RadioButton" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="100" />

                <Setter Property="Foreground" Value="DarkBlue" />

            </Style>

            <Style TargetType="CheckBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="150" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="96" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="100" />

                <Setter Property="Width" Value="100" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

            <Style TargetType="DatePicker" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="33" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="133" />

            </Style>

            <Style TargetType="TextBlock" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="31" />

                <Setter Property="Width" Value="147" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="TextWrapping" Value="Wrap" />

            </Style>

            <Style TargetType="ListBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="139" />

                <Setter Property="Width" Value="166" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

        </Grid.Resources>

        <!--nine equal Cols -->

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <!--nine equal Rows -->

        <Grid.RowDefinitions>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

    </Grid>

</UserControl>

====================================================================================

<UserControl x:Class="WpfMVLstart.OurViewModels.ucProductView"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:local="clr-namespace:WpfMVLstart.OurViewModels"

             d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ProductViewModel}}"

             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

             xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"

             mc:Ignorable="d" Background="SkyBlue"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <Grid.Resources>

            <Style TargetType="RadioButton" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="100" />

                <Setter Property="Foreground" Value="DarkBlue" />

            </Style>

            <Style TargetType="CheckBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="27" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="150" />

            </Style>

            <Style TargetType="Button" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="96" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Label" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="26" />

                <Setter Property="Width" Value="130" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="ComboBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="27" />

                <Setter Property="Width" Value="163" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

            <Style TargetType="Image" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="108" />

                <Setter Property="Width" Value="110" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Stretch" Value="Fill" />

            </Style>

            <Style TargetType="DatePicker" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="33" />

                <Setter Property="VerticalAlignment" Value="Top" />

                <Setter Property="Width" Value="133" />

            </Style>

            <Style TargetType="TextBlock" >

                <Setter Property="HorizontalAlignment" Value="Stretch" />

                <Setter Property="VerticalAlignment" Value="Stretch" />

                <Setter Property="TextWrapping" Value="Wrap" />

            </Style>

            <Style TargetType="ListBox" >

                <Setter Property="HorizontalAlignment" Value="Left" />

                <Setter Property="Height" Value="139" />

                <Setter Property="Width" Value="166" />

                <Setter Property="VerticalAlignment" Value="Top" />

            </Style>

        </Grid.Resources>

        <!--nine equal Cols -->

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

            <ColumnDefinition Width="1*"/>

        </Grid.ColumnDefinitions>

        <!--nine equal Rows -->

        <Grid.RowDefinitions>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

            <RowDefinition Height="1*"/>

        </Grid.RowDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"

                   Text="Our Products :" Background="Beige"

                   FontWeight="Black" FontSize="16"/>

        <!-- need to bind above TextBlock at a later stage -->

        <ComboBox Grid.Column="0" Grid.ColumnSpan="6" Grid.Row="2"

                  ItemsSource="{Binding}"/>

        <Button Grid.ColumnSpan="4" Content="Clear Selection" Grid.Column="7"

                Grid.Row="10" Width="110" Background="LightCoral"/>

        <Image Grid.ColumnSpan="4" Grid.Column="7"

               Grid.RowSpan="4"

               Source="/WpfMVLstart;component/sImages/Products/imagesM6EIIJJQ.jpg" />

        <TextBlock Grid.ColumnSpan="7"  Margin="0,1,0,0" Grid.Row="5"

                   Text=".. Full Details .." Background="Beige"

                    Grid.RowSpan="5"/>

        <!-- need to bind above TextBlock at a later stage -->

    </Grid>

</UserControl>

====================================================================================

====================================================================================

====================================================================================

====================================================================================

PHH - 15th. November 2013.


Adding a "mouse button down" response to the Image

Adding a "mouse button down" response to the Image

Adding a "mouse button down" response to the Image

 Previous topic Next topic

Okay then guys, let us start with some successful pictures of us getting our code and

script right - as far as a muse down on the Image control is concerned.

Here are four versions of the app working at the same time, each has had its image clicked

with the mouse a different number of times. At the moment we only have four different images

being cycled through.

Check this out below :-

========================

This looks cool, so what have we done to our XAML script which has brought this

about at runtime - when we click the image with the mouse over it ?

Check out thoroughly the following script image - there are two basic changes :-

======================================================================================================

Firstly, we see that on line 151 we now have the Source attribute bound to a new property of our VM class.

I have made for us a new string property called 'ImageSourceString', and as you can see bound this to the

attribute.

Here below are the code snippets for this addition :-

================================================================

And now we need a start string suitable for the Source image - remember, this used to be in script :-

====================================================================================================================

Secondly, in lines 152 through 155 we see see a new single event trigger, within the Triggers collection tags - look

back two images above the last one.

The script means that the 'MouseDown' event is going to be associated (linked) with the coded Command

called "ImgMouseDownCommand".

Now below we see the Command definition followed by the initialisation / registration :-

====================================================================================

And the linking of the RelayCommand to the named method 'CycleImages' - check below :-

======================================================================================

So then folks, what does this new method 'CycleImages' do for us - check the .NET code :-

================================================================================================================

Yes, this is a nice and clearer version of the 'switch' statement than I have used previously

in the Controller.

Since the value of "_next" is an integer then the values in parenthesis (braces) need also to be integers.

So what have we learned ?

Well then, we have seen how to effectively bring a UI element 'Event' into the VM code using a command.

If we can do this for the 'MouseDown' on an Image control, then we can do it for any other event too.

Just remember to try and figure out a way to get interactivity with the control attributes, and the in-built

functionality of the control itself, before reaching for the "Command to Event" approach.

Time to move on.

See you in the next sub-section where we can learn more about MVVM and the 'pattern' details etc..

PHH - 17th. November 2013.


the "MVVM way", and the 'Wrong way' !

the "MVVM way", and the 'Wrong way' !

 Previous topic Next topic

the "MVVM way", and the 'Wrong way' !

 Previous topic Next topic

What is the 'MVVM way' ? :

Quite simple really - any data displayed in any fashion (way) on a form need to be done via an attribute

on a UI element, and be backed by a property in the ViewModel object.

The attribute is bound to the 'backing' (or supporting) property.

We try NOT to use events wherever possible, even those we map to Commands.

Usually there are suitable attributes which can be used in place of choosing the event 'route', or approach.

We can demonstrate this well using a ComboBox which itself is bound to a collection of Product item objects.

In the following image we see a large text block which is used to display the concatenated details of the item

which has been selected - first of all check this out below :-

========================================================

The above form works nicely and as list selection changes the details on display are kept 'in sync', just fine.

To do the above we have used the fact that there is an attribute on the ComboBox entitled 'SelectedItem', and so

we can bind this to a property in our bound ViewModel' called "SelectedProduct" - check below :-

===================================================================================================================

Since the backing property is changed along with the UI tool functionality, the value in the 'SelectedProduct' will always

be correct - we may need to adjust how we handle the form / window opening however.

Let us now look at one way we can present the selected product details to the TextBlock as 'Text' content.

Check this out thoroughly :-

=================================================================================

Okay, it works but what about doing this in code ?

Lets move on to see .............

Making it "More MVVM like " - using code :

Before we go into the details of the improvements, let us add some date and time information to our

product data.

Here is what we get with some 'DateTime' information added - check this out :-

=========================================================

Notice that we now have Sunday - October 10th. - or the equivalent. So we need to look at the string

formatting a little later.

Here is the newly 'shaped' data - slightly collapsed :-

==========================================================================================================================================

Notice the extra line 122 added for test purposes - and also the 'null' entry for a Nullable<DateTime>.

We have had to make a change to the Constructor for our Product class - see below for how it now looks :-

============================================================================

And now it time to study some of the script and code changes.

We are going to create an extra field and property within our ViewModel class, these will hold the string object

which is the full concatenated result from the currently selected one.

*** '_fullDetails_SP' stands for full details of the selected product item.

In order to get this long string we will need a special method creating, as well.

First of all, here are the code updates - check these out below :-

=========================================================================

To make this new display approach look and work better we need to set an initial index.

So here is the amended script - check out line 119 in particular :-

=================================================================================================================

And now for the BIG change - the following script is much shorter, cleaner and easier to read.

Note that we have now bound the attribute 'Text' to the string values 'ViewModel' property called "FullDetails_SP".

===============================================================================

In order to create this long (concatenated) string we need a specially designed method.

We need to look at the structure and details of the method, before we study how to use, or apply it.

Study the next image very closely :-

===============================================================================

[ .. whoops ! - for 'to' read 'too' !! .. ]

So the above code is nothing too special, and it works as well.

I suggest you consult appendix 'D' if you wish to see an in-depth study of the date and time formats

available to us all - and probably used by very few :((

Moving on ......... we also need to see how we incorporate our new method into the 'Get/Set' structure

of our properties.

There are two things to realise as far as the changes to properties is concerned. Firstly, we need to

make a new property for 'FullDetails_SP' just as we normally would - for any VM field / property pair.

And secondly, seen in the following image, we need to run the new concatenating method after each

time the 'SelectedProduct' is changed - remember this is in-built functionality of the ComboBox control.

Study the following details, and line 74 in particular :-

==================================================================

Take care how you code the sort of thing shown above, it is easy to program a continuous 'loop'

or cycle.

Since the 'ConcatFullDetails' method sets (on line 129) the 'FullDetails_SP' property, then all required

'notification' will be done, or carried out.

Finally, lets look at the test data item, the results of displaying the product with a 'null' date added entry.

The code seems to do its work - check below :-

=========================================================

So where does all this success leave us ;-0) ???

Well, try NOT to use events, even when we map them to a Command.

Always try to use the available attributes, and bind them in a suitable manner to an appropriate VM property.

If it makes sense do the string handling and any concatenation in .NET code as we have more programming

options available to us.

We can even look at using 'Run's in code so we can set Font related properties.

Anyway, go and check out appendix 'D' to see about dates and times etc..

Lets move on .........................

The 'Wrong' way to script and code - even when it looks like MVVM :

Okay then folks, when I say the 'Wrong' way, what do I mean.

Well, I don't mean the really wrong way, like going back to before MVVM 'pattern' application, I

mean that we think we are using MVVM but are NOT because we are putting too much into the

XAML script we are using.

In the image shown below the screen seems to work as previously - BUT - we are doing a few

things we should not be doing !

Here is the runtime display :-

=========================================================

Yep! it looks and feels much like before.

But now take a look at our script for the 'ComboBox' - check out below :-

============================================================================================

Yes, line 119 shows that we have used the 'Name' attribute - remember this is a 'No - No' for MVVM.

And when we study the script below we see that we use this name in the binding for the 'Run' elements.

Check this out thoroughly :-

===============================================================================================

In the above image we see that we have 'stuff' which is very much like what guys (and me) used to

produce before we came to the rigours and restraints of the MVVM 'pattern'.

One screen output display shows we have some different script / code involved, as the null date entry

now looks different - like that below :-

==============================================

Yes, the XAML script converter turns a 'null' for the 'DateAdded' to a blank, not like our message from code.

Here is what we get from our full MVVM style approach :-

==================================

So the summary to this is that we need to try and keep our XAML script short and uncomplicated. Se that

the following is preferable and the MVVM way :-

===================================================================================

This means that the VM code handles all the logic and processing of what text is bound to the displaying

TextBlock.

This means that the VM creator and designer can have complete control of what appears on screen.

Basically, we are removing any processing from our XAML, in the way that we removed the logic processing

from our code behind file.

With the above MVVM approach we put as much as logic and Model stuff into the VM file as possible. And

this means that our code will handle just what date and time format is used for the 'DateAdded'.

Notice that in the ComboBox script we now have no 'Name' value, and the VM property 'SelectedProduct' is

being bound to the 'SelectedItem' attribute of the UI element.

==========================================================================================

Okay then, you need to both sleep on this as well as have a good think about it.

Eventually, like for me, the penny will drop, and you will "see the light" !

Good Luck .................. see you in the next sub-section.

PHH - 16th. & 17th. November 2013.


working script

working script

working script

Previous topic Next topic

===============================================================================================

<UserControl x:Class="WpfMVLstart.OurViewModels.ucProductView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:WpfMVLstart.OurViewModels"
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ProductViewModel}}"

mc:Ignorable="d" Background="SkyBlue"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="OurDataTemplate">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Path=Description}" FontStyle="Italic" />
</StackPanel>
</DataTemplate>

<Style TargetType="RadioButton" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="100" />
<Setter Property="Foreground" Value="DarkBlue" />
</Style>
<Style TargetType="CheckBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="27" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="150" />
</Style>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="96" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Label" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="ComboBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="27" />
<Setter Property="Width" Value="163" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Image" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="108" />
<Setter Property="Width" Value="110" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stretch" Value="Fill" />
</Style>
<Style TargetType="DatePicker" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="33" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="133" />
</Style>
<Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style TargetType="ListBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="139" />
<Setter Property="Width" Value="166" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Grid.Resources>
<!--nine equal Cols -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!--nine equal Rows -->
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"
Text="{Binding Path=Header}" Background="Beige"
FontWeight="Black" FontSize="16"/>

<ComboBox Grid.Column="0" Grid.ColumnSpan="6" Grid.Row="2"
ItemsSource="{Binding Path=Products}"
ItemTemplate="{StaticResource ResourceKey=OurDataTemplate}" Height="54" Grid.RowSpan="2"
Name="cbxProducts" SelectedIndex="-1">
</ComboBox>

<TextBlock Grid.ColumnSpan="7" Margin="0,1,0,0" Grid.Row="5"
Background="Beige" Grid.RowSpan="5" >
<Run Text="Selected Product Item Detail :" FontWeight="Bold"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.ProductId}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.Name}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.Description}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.DateAdded}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.Type}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.Cost}"/>
<LineBreak />
<Run Text="{Binding ElementName=cbxProducts, Path=SelectedItem.Price}"/>
</TextBlock>

<Button Grid.ColumnSpan="4" Content="Clear Selection" Grid.Column="7"
Grid.Row="10" Width="110" Background="LightCoral"/>

<Image Grid.ColumnSpan="4" Grid.Column="7"
Grid.RowSpan="4"
Source="/WpfMVLstart;component/sImages/Products/imagesM6EIIJJQ.jpg" />

</Grid>
</UserControl>

===============================================================================================

===============================================================================================

===============================================================================================

PHH - 17th. November 2013.


Designing and Creating our 'ViewModel's

Designing and Creating our 'ViewModel's

Designing and Creating our 'ViewModel's

 Previous topic Next topic

==========================================

===================================================================================

================================================================================================

===============================================

=================================================================================

============================================================================

===============================================================

==============================================================

==========================================================================

==============================================================================================================================

================================================

PHH - 12th. November 2013.


making the 'Product' ViewModel from scratch

making the 'Product' ViewModel from scratch

making the 'Product' ViewModel from scratch

 Previous topic Next topic

Well then guys, if a View and a VM (ViewModel) are to go together like 'a hand in a glove',

then when we design the VM we need to know something of the details of the View, and also

the other way around.

We will break this down soon, so that we get an idea of how to design and create both these - V & VM.

First lets look at what we have in our folder in the SE pane :-

================================================

It is only for 'Shell' and 'Supplier' where the code files are complete in an way.

The ones for Product and Customer are just 'stubs' so that the Controller code would function without

any errors being thrown up.

We can look at the top of our 'stub' code to see the following :-

=============================================================

I will now use the designed, made, and tested Model, Interface and Class for our Products V&VM.

By knowing the structure and detail of the Model and Interface we can flesh out the VM - lets start

at the 'Fields' section - study this carefully :-

=======================================================================

In the above image there are two fields ready for data from the 'injected' Model we will use / apply,

and two others for the use of the VM itself.

The _datasource and the _selectedProduct are for internal use within the VM.

So all we are going to provide to the View via the VM is a heading and a list (or collection) of objects.

Obviously, the objects are Product ones.

Let us now see how the Constructor deals with the injected Model object - that designed for Products.

Checkout this code - carefully :-

============================================================================

Yep! - so after instantiation our two fields will be set from the Model data properties, ready

for binding to the View.

Let us take a look at how our field related Properties are coded :-

=========================================================================

Okay then folks, 'so far so good' ! - lets build and run to see what we have, before we check

what the Controller does with V, VM and M.

Hint, count the list items :-

=========================================================================

[ .. the string for the Source file is presently hard coded in the XAML script .. ]

Well, obviously we could do with a data template being applied to our list ;-)

But we have proof that the header and the list seems to be displayed correctly.

Lets move on a pace ...............

Going Back to the 'View' to set the "Binding Paths" :

Since we have seen what we thought as definite proof of successful binding, we need to

take a look at the XAML script being used.

Check out lines numbered 105 and 110 :-

======================================================================================================

Applying the VM in the Controller - and Injecting it from the Model :

PHH - 15th. November 2013.


working .NET code

working .NET code

working .NET code

 Previous topic Next topic

PHH - 15th. November 2013.


Adding some Images - Folder, Sub-Folder, Files

Adding some Images - Folder, Sub-Folder, Files

Adding some Images - Folder, Sub-Folder, Files

 Previous topic Next topic

Well folks, in order to brighten up (and decorate) our three 'UserControl's (UCs) we need a few images

like those we had in the previous application - check below for what we had :-

========================================

To copy this structure to our new MVL application, do as follows :-

Make a new Folder under the main project node called 'Images', using the context menu and

then "Add, New Folder ..........."

To this new 'Images' folder, right click, and use the context menu to add three new sub- folders using the

"Add, New Folder ..........." options.

Name the three new sub-folders 'Customers', 'Products' and 'Suppliers'.

Now copy the bunch of files from the existing sub-folder in the earlier application, to the correct sub-folder

in the new app using the SE pane structure.

For each sub-folder use the context menu from a right mouse click to bring up the "Add Existing Item ..."

option screen - check the following :-

========================================================================================================

As seen in the following image make sure 'All Files' is selected, then use 'Ctrl + A' to select all and then

click add.

==============================================================================================

Get this right and you will see something like this shown below :-

=================================================

PHH - 13th. November 2013.


Designing and Creating our 'Model's

Designing and Creating our 'Model's

Designing and Creating our 'Model's

 Previous topic Next topic

An Overview - and thinking things through :

As you may have gathered by reading my other eNotes, I am very much a 'top down' design guy.

And that being the case I find it easy to thing of the User (and his requirements), the View (or GUI screen),

and then the ViewModel which fully supports the View, and so on down .............

However, there is another part of me that for MVVM wishes to start thinking from the Data point of view.

Most apps need data, and most apps need populating with back-end data before a user get to make any

interactions, or input.

This is why it is convenient to thing of the Model first, as this is where the data resides.

The 'Model for MVVM 'stuff' holds the data values, the data items, and any data item collections.

All populating data for an MVVM app comes from the Model, which is populated from SQL databases.

'Injecting' Data :

Once the Model is populated, the Model object is provided to the instantiation of the ViewModel - as a

parameter in its Constructor.

So at instantiation time, the properties of the VM are populated from those of the "injected" Model.

The VM provides the logic support and the interactivity of the View.

The View specifies in XAML just what the UI element bindings are, and maps attribute / UI properties to

data properties now populated in the VM itself.

To support what I have just said let us look at the following image of my SE pane :-

===========================================

Yes, please do notice in the image above I have renamed the folders such that they

appear in the top-down order we require Controller, View, VM and Model.

However, you will also notice that under the 'Model' folder named 'eOurModels', we have two

others relating to Interfaces and supporting Classes (and Enums).

As we go through a simple example of creating and using a Model, you will see that we must

first have the suitable classes available, as well as an appropriate interface.

Although we could probably code things to miss out the interface - at least for simpler examples - it

does make good sense to use an interface at all times. You will see as we progress in this sub-section.

Now let us look at an expanded view of the relevant part of our SE pane structure - check this out :-

===============================================

In the above details, we are interested in the "Class, Interface and Model" related to 'Suppliers'.

We first need to create a class called 'Supplier', and then an interface which uses the class, and

finally a Model which uses the interface.

This will all become clear when we follow things through, "step-by-step".

We will see the class for 'Supplier' in a lot more detail in the earlier section called "Suitable custom

classes for 'Binding' ".

For now it is sufficient to see a collapsed version for our personal reference - the full code in in the

child 'node' from this sub-folder. Check out the detail in the following image :-

=====================================================================================================================================================

You need to remember that the information in square brackets is required when we use SQL databases

through "LINQ to SQL" or the "Entity Framework" approach.

Since it does not harm to include the text attributes, it seems good practice to include them for when we

may need them. Personally, I have gotten used to including them after doing a lot of work with LINQ and SQL

generally.

Let us try another view of the Supplier class - one available in the SE pane - check this out :-

============================================================================

Fields, Properties and Methods.

Lets move on ..................

From Class to Interface :

Let us ease our way into this next part - first check the structure within the working SE pane

to see the existence of an 'ISuppier' file :-

======================================

If we then expand this a little more we see the following :-

================================================================

Four method stubs (or outlines) are specified - the signature can vary - both return types

as well as input parameters.

Keeping things as simple as we can we code our Interface "ISupplier" as seen below :-

================================================================================

However, in the above image we see that line 14 does require us to first have a class called 'Supplier'.

Here is an expanded view - shown below :-

============================================================================

So now that we have both a class called 'Supplier' and an interface called 'ISupplier', we can move

on to look in detail at the Model I have entitled "InMemDS4Supplier".

Check out the following details quite thoroughly :-

=============================================================================================================

Yep! - I am not sure that my chosen class name of "InMemDS4Supplier" is the best name, but it works

and it will do okay for now.

The above is a class which returns (or provides) four pieces of data - three strings and one item collection. The

data items being Supplier objects.

Most often the data will come from a back-end server like MS SQL server. In my simple example above, we have

hard coded three strings, and for our fourth data item we get an ObservableCollection from a STATIC method made

especially for app testing - it is in place of querying an SQL database.

To make life easy for us I included the STATIC method in the Supplier class itself.

In the following image we can see we have two STATIC methods, one returning a strongly typed List,

and the other a strongly typed ObservableCollection (OC).

It is best to always use an OC as this will track any collection item changes, additions and removals etc..

Note also that a List can be used to instantiate an OC of the same strong type.

Check this our below, as well will see more code like it in sections to come in these eNotes :-

=============================================================================================================================

So with the Model we have developed named "InMemDS4Supplier", we can 'inject into', or 'seed' the VM for Suppliers

called 'SupplierViewModel', and we can cause the following to appear at runtime - check out below :-

==================================================================================

To finish off this sub-section on our ViewModel we would be well advised to study the

following .NET code which is the Constructor which accepts the 'injected' Model data.

Study this carefully :-

======================================================================

Notice that above we have lines 41 through 44 which use the data source input object

to populate the relevant fields for use by the properties.

Moving ahead ...........................

Finally- an Interesting 'Extra' bit :

Some internal 'binding' can be seen in the images of our 'Suppliers' screen shown below :-

[ .. check the state of the 'CheckBox' UI element .. ]

============================================================================================================================

We have the 'IsChecked' attribute of the CheckBox element bound to the property of the

selected item in the list box entitled 'Reliable'.

If we take a look at the data provided we see below the two 'True' values and a 'null' - check this out :-

==================================================================================================

Notice in the above three images that 'Brown Box' has the little black square in the CheckBox, as it is set

to be 'Three State' and the data provided is 'null'.

The other two are 'True' and should be a tick, or check.

Lets now look at the binding script in the XAML section for the UI - check this :-

========================================================================================================================

The above image shows some script where it does make sense to actually 'name' a UI element.

Instead of using the name in code behind, we are using it within the XAML of the GUI itself.

On line 85 we are binding the state of the CheckBox ( 'IsChecked' ) to the 'Reliable' Boolean property on the

selected Supplier item (object) in the ListBox itself.

Note also on line 85 that we have the 'IsThreeState' attribute set true - this allows the little black square to show.

Time to move on a sub-section, see you there ....................

PHH - 14th. November 2013.

Addendum :

Although we cover this in another part of the eNotes, we may need to know the details right now.

Below is shown the simple Data Template used for the Supplier objects - the bound properties.

Study carefully lines 91 & 92 :-

==================================================================================================

And here is the result for one item of the collection :-

=============================

Also related to this - check out the use of 'Run' withing a TextBlock.


sample working .NET code

sample working .NET code

sample working .NET code

 Previous topic Next topic

========================================================================================
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//-----------------------------------
using WpfMVLstart.OurInterfaces;

namespace WpfMVLstart.OurModels
{
public class InMemDS4Supplier : ISupplier
{
//----- Fields -----
private ObservableCollection<Supplier> _supplierList;
private string _header;
private string _instruction;
private string _imageString;

//----- Constructors -----
public InMemDS4Supplier()
{
this._supplierList = Supplier.GetSupplierCollection();
this._header = "Our Suppliers :";
this._instruction = "Select from the List :";
this._imageString = "/WpfMVLstart;component/Images/Suppliers/imagesQP27TSNY.jpg";
}

//----- Methods (General) -----
//.............................

//----- Methods (ISupplier) -----
public ObservableCollection<Supplier> GetSupplierList()
{
return this._supplierList;
}

public string SetHeader()
{
return this._header;
}

public string SetImageString()
{
return this._imageString;
}

public string SetInstruction()
{
return this._instruction;
}
}
}

========================================================================================

<UserControl x:Class="WpfMVLstart.OurViews.ucSupplierView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:WpfMVLstart.OurViewModels"
d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ShellViewModel}}"

mc:Ignorable="d" Background="LightGreen"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.Resources>
<Style TargetType="RadioButton" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="100" />
<Setter Property="Foreground" Value="DarkBlue" />
</Style>
<Style TargetType="CheckBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="150" />
</Style>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="96" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Label" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="ComboBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="ItemsSource" Value="{Binding}" />
</Style>
<Style TargetType="Image" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="100" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stretch" Value="Fill" />
</Style>
<Style TargetType="DatePicker" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="33" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="133" />
</Style>

<Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="31" />
<Setter Property="Width" Value="147" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style TargetType="ListBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="139" />
<Setter Property="Width" Value="166" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Grid.Resources>

<!--======================================================================-->

<TextBlock Margin="10,53,0,0" Text="{Binding Instruction}" />

<TextBlock Margin="10,10,0,0" Text="{Binding Header}" FontSize="18"
Foreground="DarkBlue" FontWeight="Bold" />

<Button Content="Do Something" Margin="199,262,0,0" Background="Thistle" />

<CheckBox Content="{Binding Reliable}" Margin="11,248,0,0"
IsChecked="{Binding ElementName=lbxSuppliers, Path=SelectedItem.Reliable}" IsThreeState="True"/>

<ListBox Name="lbxSuppliers" Margin="10,84,143,77" ItemsSource="{Binding Suppliers}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=SupplierName}" FontWeight="Bold" />
<TextBlock Text="{Binding Path=ContactPerson}" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<Image Margin="190,10,0,0" Source="{Binding ImageString}" Stretch="Fill"/>

</Grid>
</UserControl>
========================================================================================

========================================================================================

PHH - 14th. November 2013.


Interfaces for our Models

Interfaces for our Models

Interfaces for our Models

 Previous topic Next topic

PHH - 14th. November 2013.


Views and VMs - to allow Editing of our Data

Views and VMs - to allow Editing of our Data

Views and VMs - to allow Editing of our Data

 Previous topic Next topic

PHH - 23rd. November 2013.


Making a Copy of the data object before Editing

Making a Copy of the data object before Editing

Making a Copy of the data object before Editing

 Previous topic Next topic

=========================================================================================

==========================================================================================

=========================================================

==============================================================================================================

===============================================================================================================

PHH - 23rd. November 2013.


Handling the Enabling of 'Save Edits' & 'Reset'

Handling the Enabling of 'Save Edits' & 'Reset'

Handling the Enabling of 'Save Edits' & 'Reset'

 Previous topic Next topic

This sub-section is simple in theory, but a little trickier to code when it comes down to it ;-)

Basically, the three Buttons on the 'View' - shown below :-

=========================================================

Need to be enabled ONLY when there is an action possible, behind each one of them.

By this I mean that a button is enabled (made active) only once there is a possible 'action'

which can be made as a consequence of clicking or pressing it - touch tap too?

To understand what is required we need to take each button in turn and follow through some

interactive possibilities.

Let us start with the 'Save Edits' button.

Before we make an edit / change, to any one of the fields of the selected customer, we need to have

the Button disabled - or greyed out as we often say !

Here shown below is the initial state of the 'View' before editing :-

=============================

The 'Save Edits' button can't be used since we have no changes to save.

The 'Reset' button on the other hand can be left enabled at all times since it simply refreshes the set

of fields for the selected customer.

PHH - 24th. November 2013.


Forcing an update in the 'Back-End' data source

Forcing an update in the 'Back-End' data source

Forcing an update in the 'Back-End' data source

 Previous topic Next topic

========================================================================================================================

======================================================================================================================

=========================================================================================================================================

=========================================================================================================

====================================================================================

PHH - 24th. November 2013.


Overview of our use of the 'Controller'

Overview of our use of the 'Controller'

Overview of our use of the 'Controller'

 Previous topic Next topic

PHH - 24th. November 2013.


Use of 'ControlTemplate' to tidy script into Resources section

Use of 'ControlTemplate' to tidy script into Resources section

 Previous topic Next topic

Use of 'ControlTemplate' to tidy script into Resources section

 Previous topic Next topic

Making a Start :

depending on the knowledge and skills of the coder / developer, we can script out body of the

mark-up dircetly, without need to using the Resources section of the Window, 'UserControl' or Grid.

Here is an example which I had working, before I decided to try and reduce the lines of script :-

====================================================================================================

Above we only see three TextBox definitions, when in fact we have eight - quite a few lines of script.

Let us know see the first way we can reduce this - by seeing the working results, after some messing

around by me, and also me learning more about templates in general, and 'ControlTemplate's in

particular.

Check this out as an improvement :-

==========================================================================

In fact we will see later that we can further improve the above script by removing another eight lines.

But for the moment let us check out the Styles and Templates which I have gotten to work for us.

Look carefully at the following script details :-

========================================================================================================================

Above we can see a number of things from which we can learn.

Firstly, one object definition is based on the other - that is quite commonly seen - but because we

are calling on 'Mine5' before it has been read-in or processed, we need to use 'DynamicResource' in line 22, in the

Style definition.

When I reverse the order of the Style definitions I can then revert to using 'StaticResource' in line 29 shown below :-

========================================================================================================================

And this is simply because when the mark-up processor gets to needing 'Mine5' it is already aware of its details.

To new guys the above script for the Style and Templates can be VERY confusing - appearing complicated.

However, I can assure you that they are NOT rocket science at all. We just need some day-to-day experience and

also some idea of how to read the script lines.

You can help yourself by referring to the earlier sections on Styles and Templates - see "Tiding our script - Resources,

Styles & Templates" within the "XAML - getting the 'Basics' right" main section.

In the above script lines 33 & 34 are the most crucial / important.

If you are new to XAML then don't panic, just do it the easier way for now and put all the script in the body of your mark-up

script. It is easier that way, BUT, using Resources is the way to go - we need to develop skills, and using Resources is

just one of those skills we MUST acquire for the future.

Moving on ... getting even tidier ................

Going even a Step Further :

If we wish to see just how tidy our TextBox definitions can get, then study the following image carefully :-

===========================================================================

Note that in the above image we have gotten down to just one attribute assignment / association.

It requires that we have a new Style (for 'TextBox') without a name - we say this is 'Implicit', and

any TextBox without a defined Style will have this applied by the mark-up system.

Here is the new implicit Style we talk of above :-

=============================================================================================================

So then, how easy is that ?

Let us leave things at that, enough for now.

Shall we move on to the next sub-section to see what we can learn there ?

PHH - 25th. November 2013.


Use of 'DataTemplate' to tidily present list items

Use of 'DataTemplate' to tidily present list items

Use of 'DataTemplate' to tidily present list items

 Previous topic Next topic

There is one important aspect of scripting in XAML which new guys come to VERY quickly once

they start to write apps for WPF, WinRT and Phone8, and that is how to present list items that are

held in Collections bound to ListBox, ComboBox and DataGrid controls.

The List type boxes in particular, need to call on skills from the developer regarding the design and use

of 'DataTemplate's.

Here is a ListBox control which is bound to a collection of Customer business objects - note how

it looks when we are NOT using a 'DataTemplate' - check this out :-

========================================================

If you count the list items we do get the correct number, so we are doing something right ;-)

And we can really improve this by adding just a few script lines - see below :-

=================================================================================================

The 'DataTemplate' is usually mainly a bunch of 'Container' elements as well as text related controls.

However, as you will see later in this section, we can have Image controls too.

Checkout below how the defined 'DataTemplate' is associated with the UI control - see below :-

========================================================================================

In fact line 72 can be used for the same items collection when bound to a ComboBox.

Let us see in the two images seen below just what this may look like - the first one is from the

script we have see above for the template - the second (green) one is sightly different :-

=================================================================

So how does the template for the Suppliers screen look - check this out below :-

==================================================================================================

The answer is, 'not a lot', as we simply have different bound properties.

And so what about something a lot more fancy ?

The next image is that from a drop list control with 'GlobalPlaceTime4' object items within

the collection. The time is actually ticking, with the displays changing each 5 seconds - check

this out for detail :-

=====================================================================================

Obviously, if the time is changing every five seconds then we must have some sort of timer in operation.

However, we are really more interested in this section, in the detail of the 'DataTemplate' script lines.

Study the following VERY thoroughly :-

===================================================================================================================================================

If you are not ready for such a complex DataTemplate, then don't worry, we can

do a whole lot with something simpler ;-0)

Before we move on, look at line 41 to see how the Image control gets its Source via binding.

Lets move on to the next sub-section.

See you there ......................

PHH - 25th. November 2013.


Example (Vulcan 3) - MVVMLight - 3 UC project

Example (Vulcan 3) - MVVMLight - 3 UC project

Example (Vulcan 3) - MVVMLight - 3 UC project

 Previous topic Next topic

Open VS 2012 and close any open files, projects or solutions.

From the menu bar select 'File, New, Project ......'

In the 'New Project' dialog screen make selections and inputs as shown below :-

================================================================================================================

Notice that I have available to me the choice to add the new project to 'Source Control'. I will choose to do so.

Here is what my 'TFS' dialog looks like :-

=========================================================

This results in the SE pane being filled as shown below :-

===================================================

Notice the small icons shown attached to the above files.

Now we need to check out the References which have been added by the Template.

Check these out :-

=========================================

Just to see that all is okay, lets do a build and run - check this out :-

==============================================================================

Well, at least our new app compiles and runs ;-) - even if it is doing nothing much !

Adding References :

Before we start to add some references, lets see which are present in the working C# application.

I have tired to highlight any which are currently missing from our Vulcan project - check this out :-

========================================================

Yes, we have eight already, and need another eight, including the GalaSoft assemblies.

I will now try to add the extra few, but will try the six belonging to the Microsoft frameworks before

we attempt to add the 'GalaSoft' ones.

Here is my attempt to find and add the 'CSharp' reference :-

[ .. don't think because it says C# that we don't need it - there are others stuff it contains .. ]

===================================================================

Here are the four I managed to find and then add :-

============================================

It seems like a good idea to now try to use the NuGet packages tool to find the GalaSoft assemblies.

Once we have done that, we can see just what these add to the References section.

Ways to add the other four References :

Okay then folks, I tired to use the 'NuGet' approach as seen in my next image shown below :-

==========================================================

But unfortunately, I got an error box I did not capture, and it no longer shows in the Context Menu.

I tried a few other ways to redeem the situation, but failed, so I have cleaned up the SE pane once

more and will try another way to get the References we need.

Okay guys, we need some signs of success, to drive us forwards - check this out below :-

==================================================

Yes, it would appear that we now have all 16 reference entries present, and the app still

compiles and runs OK - no warnings or errors.

So how did I get the references into the References collection ?

Quite simple, I used good old 'Copy and Paste'.

With the C# working solution open in one instance of VS2012, I used the context menu to assist

me in copying an item, or multiple items - check below :-

===================================================================================

Then I highlighted the References node in the Vulcan app and did a Context Menu option of 'Paste'.

See the following example :-

==============================================================

Since this seemed to work OK I continued the process, as well as trying multiple selections too.

So with a quick build and run to see all was well I decide to Check-In for a first time the complete project.

The image below is for the TFS first Check-In - yes, TFS is our Source Control :-

=======================================================

The result of the Check-In is as seen in the following image :-

============================================================

And the resulting change to the small icons in the SE pane is shown below :-

=============================================

Okay then, time to move on .......................

See you in the first child folder from here ..........

PHH - 18th. November 2013.


Setting up the App - 'Controller', launch, and 'shell' screen

Setting up the App - 'Controller', launch, and 'shell' screen

 Previous topic Next topic

Setting up the App - 'Controller', launch, and 'shell' screen

 Previous topic Next topic

The easiest way for us to get our first Vulcan 3 MVL app going, is for us to look at the working C#

app for XAML script, and do some copy and pasting, as well as using the Reflector conversion of .NET code.

Let us start right at the 'top' - at the App.xaml & APp.xaml.prg.

Here is what we have at the moment - check this out :-

===================================================================================

And the following is what we have in the working app - study carefully :-

=====================================================================================================

PHH - 18th. November 2013.


Making the 'UserControl' sub-screens - "Views"

Making the 'UserControl' sub-screens - "Views"

Making the 'UserControl' sub-screens - "Views"

 Previous topic Next topic

PHH - 19th. November 2013.


Creating the 'ViewModel's - VMs

Creating the 'ViewModel's - VMs

Creating the 'ViewModel's - VMs

 Previous topic Next topic

PHH - 19th. November 2013.


Making the Interfaces and Models

Making the Interfaces and Models

Making the Interfaces and Models

 Previous topic Next topic

PHH - 19th. November 2013.


Designing the Enums and Classes

Designing the Enums and Classes

Designing the Enums and Classes

 Previous topic Next topic

PHH - 19th. November 2013.


Providing the Images and their source strings

Providing the Images and their source strings

Providing the Images and their source strings

 Previous topic Next topic

==================================

===========================================

=====================================================================================================================================================

====================================================================================================

===========================================

==========================================================

==========================================================================================

PHH - 19th. November 2013.


full working code and script

full working code and script

full working code and script

 Previous topic Next topic

=========================================================================================
<Application x:Class="WpfMVLstartVN.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="MVL_startup"
Exit="MVL_exit"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d"
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006" >

<Application.Resources>

</Application.Resources>
</Application>
=========================================================================================

#using System
#using System.Collections.Generic
#using System.Configuration
#using System.Data
#using System.Linq
#using System.Windows
//=================================

#using WpfMVLstartVN.OurViewModels
#using WpfMVLstartVN.OurViews

BEGIN NAMESPACE WpfMVLstartVN

/// <summary>
/// Interaction logic for App.xaml
/// </summary>
partial class App inherit System.Windows.Application

//----- Fields -----
private _controller as MVL_controller

//----- Methods -----
private method MVL_startup(sender as Object, e as System.Windows.StartupEventArgs) as void
self:_controller := MVL_controller{}
self:_controller:Start()
return

private method MVL_exit(sender as Object, e as System.Windows.ExitEventArgs) as void
self:_controller := null
return

end class

END NAMESPACE
=========================================================================================

//----- OurController.prg -----
#using System
#using System.Windows
#using GalaSoft.MvvmLight.Messaging
//=================================
#using WpfMVLstartVN.OurViewModels
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN.OurModels

BEGIN NAMESPACE WpfMVLstartVN

class MVL_controller
//----- Fields -----
private _CVM as CustomerViewModel
private _datasourceP as InMemDS4Product
private _datasourceS as InMemDS4Supplier
private _PVM as ProductViewModel
private _shellvm as ShellViewModel
private _shellvw as ShellView
private _SVM as SupplierViewModel
private _ucCV as ucCustomerView
private _ucPV as ucProductView
private _ucSV as ucSupplierView

//----- Properties -----

//----- Constructors -----
constructor()
super()
Messenger.Default:Register<ControllerMessage>(self, System.Action<ControllerMessage>{ self, @MessageProcessor() })
self:Initialize()
return

//----- Methods -----
method Initialize() as void
//
self:_datasourceS := InMemDS4Supplier{}
self:_datasourceP := InMemDS4Product{}
self:_shellvm := ShellViewModel{}
self:_shellvw := ShellView{}
self:_shellvw:DataContext := self:_shellvm
self:_ucCV := ucCustomerView{}
self:_CVM := CustomerViewModel{}
self:_ucCV:DataContext := self:_CVM
self:_ucPV := ucProductView{}
self:_PVM := ProductViewModel{self:_datasourceP}
self:_ucPV:DataContext := self:_PVM
self:_ucSV := ucSupplierView{}
self:_SVM := SupplierViewModel{self:_datasourceS}
self:_ucSV:DataContext := self:_SVM

private method MessageProcessor(msg as ControllerMessage) as void
//
do case
case (msg:VAction == ViewAction.Close && msg:VType == ViewType.Shell)
self:Stop()
return

case (msg:VAction == ViewAction.Open && msg:VType == ViewType.Customers)
self:_shellvw:ccSwapping:DataContext := self:_ucCV
return

case (msg:VAction == ViewAction.Open && msg:VType == ViewType.Products)
self:_shellvw:ccSwapping:DataContext := self:_ucPV
return

case (msg:VAction == ViewAction.Open && msg:VType == ViewType.Suppliers)
self:_shellvw:ccSwapping:DataContext := self:_ucSV
return
endcase
return
//============================================================================================

method Start() as void
self:_shellvw:Show()
return

method Stop() as void
self:_shellvw:Close()
return

end class

//=====================================================================================================

class ControllerMessage
//----- Fields -----

//----- Constructors -----
constructor()
super()
return

constructor(vaction as ViewAction, vtype as ViewType, daction as DataAction, dataid as System.Nullable<int>)
super()
self:VAction := vaction
self:VType := vtype
self:DAction := daction
self:dataid := dataid
return

constructor(vaction as ViewAction, vtype as ViewType, daction as DataAction)
super()
self:VAction := vaction
self:VType := vtype
self:DAction := daction
return

//----- Properties -----
property DAction as DataAction auto

property Dataid as System.Nullable<int> auto

property VAction as ViewAction auto

property VType as ViewType auto

//----- Methods -----
end class

END NAMESPACE //----- WpfMVLstartVN -----

=========================================================================================
<Window x:Class="WpfMVLstartVN.OurViews.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local="clr-namespace:WpfMVLstartVN.OurViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

mc:Ignorable="d"

Title="VULCAN 3 : Swapping UCs - in/out of a CC :"
Height="440" Width="600" Background="Bisque">
<Grid>
<Grid.Resources>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.ColumnSpan" Value="2"/>
<Setter Property="Width" Value="111"/>
<Setter Property="Height" Value="32" />
</Style>
</Grid.Resources>

<Grid.ColumnDefinitions>
<!--nine equal Cols for UC 300 width-->
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!--nine equal Rows for UC 300 height-->
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>

<Border Grid.Column="2" Grid.Row="1"
Grid.ColumnSpan="5" Grid.RowSpan="7"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
BorderBrush="DarkBlue" BorderThickness="4">

<ContentControl Name="ccSwapping" Content="{Binding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Border>

<Button Name="pbCustomer" Content="Customer" Background="LightCoral" Grid.Row="1"
Command="{Binding Path=DisplayCustomersCommand}" />

<Button Name="pbProduct" Content="Product" Background="LightBlue" Grid.Row="2"
Command="{Binding Path=DisplayProductsCommand}" />

<Button Name="pbSupplier" Content="Supplier" Background="LightGreen" Grid.Row="3"
Command="{Binding Path=DisplaySuppliersCommand}" />

<Button Content="Close Shell" Background="Red" Foreground="Gold" FontWeight="Bold" Grid.Row="8"
Command="{Binding CloseShellCommand}" />

</Grid>
</Window>

<!--d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ShellViewModel}}"-->
=========================================================================================

//----- ShellView.xaml.prg -----
#using System
#using System.Windows
//======================================
#using WpfMVLstartVN
#using WpfMVLstartVN.OurViewModels

begin namespace WpfMVLstartVN.OurViews

/// <summary>
/// Interaction logic for ShellView.xaml
/// </summary>
partial class ShellView inherit Window

constructor()
super()
InitializeComponent()
return

end class

end namespace
=========================================================================================

<UserControl x:Class="WpfMVLstartVN.ucCustomerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:WpfMVLstartVN.OurViewModels"

mc:Ignorable="d" Background="LightCoral"
d:DesignHeight="300" d:DesignWidth="300" >

<Grid>

</Grid>
</UserControl>
=========================================================================================
#using System
#using System.Collections.Generic
#using System.Linq
#using System.Text
#using System.Windows
#using System.Windows.Controls
#using System.Windows.Data
#using System.Windows.Documents
#using System.Windows.Input
#using System.Windows.Media
#using System.Windows.Media.Imaging
#using System.Windows.Navigation
#using System.Windows.Shapes
//======================================
#using WpfMVLstartVN.OurViewModels
#using WpfMVLstartVN

BEGIN NAMESPACE WpfMVLstartVN

/// <summary>
/// Interaction logic for ucCustomerView.xaml
/// </summary>
PARTIAL CLASS ucCustomerView INHERIT UserControl

CONSTRUCTOR()
SUPER()
InitializeComponent()
RETURN

END CLASS

END NAMESPACE
=========================================================================================

<UserControl x:Class="WpfMVLstartVN.OurViews.ucProductView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF45"

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:WpfMVLstartVN.OurViewModels"

mc:Ignorable="d" Background="SkyBlue"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="OurDataTemplate">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Path=Description}" FontStyle="Italic" />
</StackPanel>
</DataTemplate>

<Style TargetType="RadioButton" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="100" />
<Setter Property="Foreground" Value="DarkBlue" />
</Style>
<Style TargetType="CheckBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="27" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="150" />
</Style>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="96" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Label" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="ComboBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="27" />
<Setter Property="Width" Value="163" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Image" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="108" />
<Setter Property="Width" Value="110" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stretch" Value="Fill" />
</Style>
<Style TargetType="DatePicker" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="33" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="133" />
</Style>
<Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style TargetType="ListBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="139" />
<Setter Property="Width" Value="166" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Grid.Resources>
<!--nine equal Cols -->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<!--nine equal Rows -->
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>

<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="5"
Text="{Binding Path=Header}" Background="Beige"
FontWeight="Black" FontSize="16"/>

<ComboBox Grid.Column="0" Grid.ColumnSpan="6" Grid.Row="2"
ItemsSource="{Binding Path=Products}"
ItemTemplate="{StaticResource ResourceKey=OurDataTemplate}"
SelectedItem="{Binding Path=SelectedProduct}"
SelectedIndex="{Binding Path=OurIndex}" Height="54" Grid.RowSpan="2">
</ComboBox>

<TextBlock Grid.ColumnSpan="7" Margin="0,1,0,0" Grid.Row="5"
Background="Beige" Grid.RowSpan="5"
Text="{Binding Path=FullDetails_SP}"/>

<Button Grid.ColumnSpan="4" Content="Clear Selection" Grid.Column="7"
Grid.Row="10" Width="110" Background="LightCoral"
Command="{Binding Path=ClearIndexCommand}"/>

<Image Grid.ColumnSpan="4" Grid.Column="7"
Grid.RowSpan="4"
Source="{Binding Path=ImageSourceString}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding Path=ImgMouseDownCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
</UserControl>
=========================================================================================

#using System
#using System.Collections.Generic
#using System.Linq
#using System.Text
#using System.Windows
#using System.Windows.Controls
#using System.Windows.Data
#using System.Windows.Documents
#using System.Windows.Input
#using System.Windows.Media
#using System.Windows.Media.Imaging
#using System.Windows.Navigation
#using System.Windows.Shapes
//======================================
#using WpfMVLstartVN.OurViewModels
#using WpfMVLstartVN

BEGIN NAMESPACE WpfMVLstartVN.OurViews

/// <summary>
/// Interaction logic for ucProductView.xaml
/// </summary>
PARTIAL CLASS ucProductView INHERIT UserControl

CONSTRUCTOR()
SUPER()
InitializeComponent()
RETURN

END CLASS

END NAMESPACE
=========================================================================================

<UserControl x:Class="WpfMVLstartVN.OurViews.ucSupplierView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

xmlns:local="clr-namespace:WpfMVLstartVN.OurViewModels"

mc:Ignorable="d" Background="LightGreen"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.Resources>
<Style TargetType="RadioButton" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="100" />
<Setter Property="Foreground" Value="DarkBlue" />
</Style>
<Style TargetType="CheckBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="150" />
</Style>
<Style TargetType="Button" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="96" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="Label" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
<Style TargetType="ComboBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="26" />
<Setter Property="Width" Value="130" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="ItemsSource" Value="{Binding}" />
</Style>
<Style TargetType="Image" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="100" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Stretch" Value="Fill" />
</Style>
<Style TargetType="DatePicker" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="33" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="Width" Value="133" />
</Style>

<Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="31" />
<Setter Property="Width" Value="147" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
<Style TargetType="ListBox" >
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Height" Value="139" />
<Setter Property="Width" Value="166" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Grid.Resources>

<!--======================================================================-->

<TextBlock Margin="10,53,0,0" Text="{Binding Instruction}" />

<TextBlock Margin="10,10,0,0" Text="{Binding Header}" FontSize="18"
Foreground="DarkBlue" FontWeight="Bold" />

<Button Content="Do Something" Margin="199,262,0,0" Background="Thistle" />

<CheckBox Content="{Binding Reliable}" Margin="11,248,0,0"
IsChecked="{Binding ElementName=lbxSuppliers, Path=SelectedItem.Reliable}" IsThreeState="True"/>

<ListBox Name="lbxSuppliers" Margin="10,84,143,77" ItemsSource="{Binding Suppliers}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=SupplierName}" FontWeight="Bold" />
<TextBlock Text="{Binding Path=ContactPerson}" FontStyle="Italic" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

<Image Margin="190,10,0,0" Source="{Binding ImageString}" Stretch="Fill"/>

</Grid>
</UserControl>

<!--d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type local:ShellViewModel}}"-->

<!--nine equal Cols -->
<!--<Grid.ColumnDefinitions>

<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>-->
<!--nine equal Rows -->
<!--<Grid.RowDefinitions>

<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>-->

=========================================================================================

#using System
#using System.Collections.Generic
#using System.Linq
#using System.Text
#using System.Windows
#using System.Windows.Controls
#using System.Windows.Data
#using System.Windows.Documents
#using System.Windows.Input
#using System.Windows.Media
#using System.Windows.Media.Imaging
#using System.Windows.Navigation
#using System.Windows.Shapes
//======================================
#using WpfMVLstartVN.OurViewModels
#using WpfMVLstartVN

BEGIN NAMESPACE WpfMVLstartVN.OurViews

/// <summary>
/// Interaction logic for ucSupplierView.xaml
/// </summary>
PARTIAL CLASS ucSupplierView INHERIT UserControl

CONSTRUCTOR()
SUPER()
InitializeComponent()
RETURN

END CLASS

END NAMESPACE
=========================================================================================

//----- CustomerViewModel.prg -----
#using GalaSoft.MvvmLight
//-------------------------------------
#using GalaSoft.MvvmLight.Command
#using GalaSoft.MvvmLight.Messaging
#using System.Windows.Controls
//-------------------------------------
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN

begin namespace WpfMVLstartVN.OurViewModels

class CustomerViewModel inherit ViewModelBase

//----- Fields -----
private _name as string

//----- Constructors -----
constructor()
super()
self:InitialiseCommands()
return

//----- Methods -----
private method CloseCustomerView() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Customers, DataAction.None, null})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Customers, DataAction.None})

private method InitialiseCommands() as void
self:CloseCustomerViewCommand := RelayCommand{System.Action{ self, @CloseCustomerView() }}

//----- Properties -----
property CloseCustomerViewCommand as RelayCommand auto

property Name as string
get
return self:_name
end get
set
self:_name := value
self:RaisePropertyChanged("Name")
end set
end property

end class

END NAMESPACE //----- WpfMVLstartVN.OurViewModels -----

=========================================================================================

//----- ProductViewModel.prg -----
#using GalaSoft.MvvmLight
#using GalaSoft.MvvmLight.Command
#using GalaSoft.MvvmLight.Messaging
#using System.Windows.Controls
//-------------------------------------
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN
#using WpfMVLstartVN.OurModels

begin namespace WpfMVLstartVN.OurViewModels

class ProductViewModel inherit ViewModelBase
//----- Fields -----
private _datasource as InMemDS4Product
private _fullDetails_SP as string
private _header as string
private _imageSourceString as string
private _next as long
private _ourIndex as string
private _products as System.Collections.ObjectModel.ObservableCollection<Product>
private _selectedProduct as Product

//----- Constructors -----
constructor()
super()
self:_next := 1
self:InitialiseCommands()
return

constructor(DataSource as InMemDS4Product)
super()
self:_next := 1
self:_datasource := DataSource
self:_header := self:_datasource:SetHeader()
self:_products := self:_datasource:GetProductCollection()
self:InitialiseCommands()
self:_fullDetails_SP := ".. yet to be set .."
self:_selectedProduct := Product{}
self:_ourIndex := "-1"
self:_imageSourceString := "/sImages/Products/imagesM6EIIJJQ.jpg"
return

//----- Methods -----
private method ClearIndex() as void
self:OurIndex := "-1"
self:FullDetails_SP := ".. reset .."
return

private method CloseProductView() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Products, DataAction.None, null})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Products, DataAction.None})
return

private method ConcatFullDetails() as void
local str as string
local str2 as string
local dateAdded as System.Nullable<System.DateTime>
local time2 as System.DateTime
local str3 as string

str := chr(10)
str2 := ""
dateAdded := self:_selectedProduct:DateAdded
time2 := System.DateTime{2001, 1, 1}
if (IIF(dateAdded:HasValue,(dateAdded:GetValueOrDefault() > time2),false))
str2 := string.Concat(self:_selectedProduct:dateAdded:Value:ToString("ddd dd MMM yyyy"), str)
else
str2 := String.Concat(".. too early !? ..", str)
endif
str3 := ""
str3 := string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(string.Concat(str3, ;
"Code - Selected Product Detail :", str), self:_selectedProduct:ProductId:ToString(), str), ;
self:_selectedProduct:Name, str), self:_selectedProduct:Description, str), str2), ;
self:_selectedProduct:Cost:ToString(), str), self:_selectedProduct:Price:ToString(), str)

self:FullDetails_SP := str3
return

private method CycleImages() as void
self:_next++
if ((self:_next < 1) .or. (self:_next > 5))
self:_next := 1
endif
do case
case ( self:_next == 1 )
self:ImageSourceString := "/sImages/Products/imagesM6EIIJJQ.jpg"
return
case ( self:_next == 2 )
self:ImageSourceString := "/sImages/Products/imagesMQHEDGWJ.jpg"
return
case ( self:_next == 3 )
self:ImageSourceString := "/sImages/Products/imagesVTD3I1PP.jpg"
return
case ( self:_next == 4 )
self:ImageSourceString := "/sImages/Products/VWcar.png"
return
case ( self:_next == 5 )
self:ImageSourceString := "/sImages/Products/watchdigital.png"
return
endcase

private method InitialiseCommands() as void
self:CloseProductViewCommand := RelayCommand{System.Action{ self, @CloseProductView() }}
self:ClearIndexCommand := RelayCommand{System.Action{ self, @ClearIndex() }}
self:ImgMouseDownCommand := RelayCommand{System.Action{ self, @CycleImages() }}
return

//----- Properties -----
property ClearIndexCommand as RelayCommand auto

property CloseProductViewCommand as RelayCommand auto

property FullDetails_SP as string
get
return self:_fullDetails_SP
end get
set
self:_fullDetails_SP := value
self:RaisePropertyChanged("FullDetails_SP")
end set
end property

property Header as string
get
return self:_header
end get
set
self:_header := value
self:RaisePropertyChanged("Header")
end set
end property

property ImageSourceString as string
get
//
return self:_imageSourceString
end get
set
self:_imageSourceString := value
self:RaisePropertyChanged("ImageSourceString")
end set
end property

property ImgMouseDownCommand as RelayCommand auto

property OurIndex as string
get
return self:_ourIndex
end get
set
self:_ourIndex := value
self:RaisePropertyChanged("OurIndex")
end set
end property

property Products as System.Collections.ObjectModel.ObservableCollection<Product>
get
return self:_products
end get
set
self:_products := value
self:RaisePropertyChanged("Products")
end set
end property

property SelectedProduct as Product
get
return self:_selectedProduct
end get
set
self:_selectedProduct := value
self:RaisePropertyChanged("SelectedProduct")
self:ConcatFullDetails()
end set
end property

end class

end namespace //----- WpfMVLstartVN.OurViewModels -----

=========================================================================================

//----- ShellViewModel.prg -----
#using GalaSoft.MvvmLight
//-------------------------------------
#using GalaSoft.MvvmLight.Command
#using GalaSoft.MvvmLight.Messaging
#using System.Windows.Controls
//-------------------------------------
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN

BEGIN NAMESPACE WpfMVLstartVN.OurViewModels

class ShellViewModel inherit ViewModelBase
//----- Fields -----
private _shellContentControl as System.Windows.Controls.ContentControl

//----- Constructors -----
constructor()
super()
self:InitialiseCommands()
return

//----- Methods -----
private method CloseShell() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Shell, DataAction.None, false})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Shell, DataAction.None})

private method DisplayCustomers() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Customers, DataAction.None, false})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Customers, DataAction.None})

private method DisplayProducts() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Products, DataAction.None, false})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Products, DataAction.None})

private method DisplaySuppliers() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Suppliers, DataAction.None, false})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Open, ViewType.Suppliers, DataAction.None})

private method InitialiseCommands() as void
self:CloseShellCommand := RelayCommand{System.Action{ self, @CloseShell() }}
self:DisplayCustomersCommand := RelayCommand{System.Action{ self, @DisplayCustomers() }}
self:DisplayProductsCommand := RelayCommand{System.Action{ self, @DisplayProducts() }}
self:DisplaySuppliersCommand := RelayCommand{System.Action{ self, @DisplaySuppliers() }}
return

//----- Properties -----
property CloseShellCommand as RelayCommand auto

property DisplayCustomersCommand as RelayCommand auto

property DisplayProductsCommand as RelayCommand auto

property DisplaySuppliersCommand as RelayCommand auto

property ShellContentControl as System.Windows.Controls.ContentControl
get
return self:_shellContentControl
end get
set
self:_shellContentControl := value
self:RaisePropertyChanged("ContentControl")
end set
end property

end class

end namespace //----- WpfMVLstartVN.OurViewModels -----

=========================================================================================

//----- SupplierViewModel.prg -----
#using GalaSoft.MvvmLight
//-------------------------------------
#using GalaSoft.MvvmLight.Command
#using GalaSoft.MvvmLight.Messaging
#using System.Windows.Controls
//-------------------------------------
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN
#using WpfMVLstartVN.OurModels

begin namespace WpfMVLstartVN.OurViewModels

class SupplierViewModel inherit ViewModelBase
//----- Fields -----
private _datasource as InMemDS4Supplier
private _header as string
private _imageString as string
private _instruction as string
private _name as string
private _reliable as string
private _suppliers as System.Collections.ObjectModel.ObservableCollection<Supplier>

//----- Constructors -----
constructor()
super()
self:InitialiseCommands()
return

constructor(DataSource as InMemDS4Supplier)
super()
self:_datasource := DataSource
self:_header := self:_datasource:SetHeader()
self:_imageString := self:_datasource:SetImageString()
self:_instruction := self:_datasource:SetInstruction()
self:_suppliers := self:_datasource:GetSupplierList()
self:_reliable := "Can be relied on :"
self:InitialiseCommands()
return

//----- Methods -----
private method CloseSupplierView() as void
//Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Suppliers, DataAction.None, null})
Messenger.Default:Send<ControllerMessage>(ControllerMessage{ViewAction.Close, ViewType.Suppliers, DataAction.None})

private method InitialiseCommands() as void
self:CloseSupplierViewCommand := RelayCommand{System.Action{ self, @CloseSupplierView() }}

//----- Properties -----
property CloseSupplierViewCommand as RelayCommand auto

property Header as string
get
return self:_header
end get
set
self:_header := value
self:RaisePropertyChanged("Header")
end set
end property

property ImageString as string
get
return self:_imageString
end get
set
self:_imageString := value
self:RaisePropertyChanged("ImageString")
end set
end property

property Instruction as string
get
return self:_instruction
end get
set
self:_instruction := value
self:RaisePropertyChanged("Instruction")
end set
end property

property Name as string
get
return self:_name
end get
set
self:_name := value
self:RaisePropertyChanged("Name")
end set
end property

property Reliable as string
get
return self:_reliable
end get
set
self:_reliable := value
self:RaisePropertyChanged("Reliable")
end set
end property

property Suppliers as System.Collections.ObjectModel.ObservableCollection<Supplier>
get
return self:_suppliers
end get
set
self:_suppliers := value
self:RaisePropertyChanged("Suppliers")
end set
end property

end class

end namespace //----- WpfMVLstartVN.OurViewModels -----

=========================================================================================

//----- InMemDS4Product.prg -----
#using System
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN
#using WpfMVLstartVN.OurInterfaces

begin namespace WpfMVLstartVN.OurModels

class InMemDS4Product implements IProduct
//----- Fields -----
private _header := "Our Products :" as string
private _productList := Product.GetProductCollection() as System.Collections.ObjectModel.ObservableCollection<Product>

//----- Methods -----
virtual method GetProductCollection() as System.Collections.ObjectModel.ObservableCollection<Product>
return self:_productList

virtual method SetHeader() as string
return self:_header

end class

end namespace //----- WpfMVLstart.OurModels -----
=========================================================================================

//----- InMemDS4Supplier.prg -----
#using System
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN
#using WpfMVLstartVN.OurInterfaces

begin namespace WpfMVLstartVN.OurModels

class InMemDS4Supplier implements ISupplier
//----- Fields -----
private _header := "Our Suppliers :" as string
private _imageString := "/WpfMVLstart;component/Images/Suppliers/imagesQP27TSNY.jpg" as string
private _instruction := "Select from the List :" as string
private _supplierList := Supplier.GetSupplierCollection() as System.Collections.ObjectModel.ObservableCollection<Supplier>

//----- Methods -----
virtual method GetSupplierList() as System.Collections.ObjectModel.ObservableCollection<Supplier>
return self:_supplierList

virtual method SetHeader() as string
return self:_header

virtual method SetImageString() as string
return self:_imageString

virtual method SetInstruction() as string
return self:_instruction

end class

end namespace //----- WpfMVLstartVM.OurModels

=========================================================================================

//----- IProduct.prg -----
#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN

begin namespace WpfMVLstartVN.OurInterfaces

interface IProduct
//----- Methods -----
method GetProductCollection() as System.Collections.ObjectModel.ObservableCollection<Product>
method SetHeader() as string
end interface

end namespace //----- WpfMVLstartVN.OurInterfaces -----

=========================================================================================

//----- ISupplier.prg -----

#using System.Windows
#using WpfMVLstartVN.OurViews
#using WpfMVLstartVN

begin namespace WpfMVLstartVN.OurInterfaces

interface ISupplier
//----- Methods -----
method GetSupplierList() as System.Collections.ObjectModel.ObservableCollection<Supplier>
method SetHeader() as string
method SetImageString() as string
method SetInstruction() as string
end interface

end namespace //----- WpfMVLstartVN.OurInterfaces -----
=========================================================================================

//----- OurEnumsAndClasses.prg -----
#using System

begin namespace WpfMVLstartVN

enum DataAction as int
member CreateData:=1
member EditData:=2
member None:=0
end enum

enum ViewType as int
member Customers:=0
member Products:=1
member Shell:=3
member Suppliers:=2
end enum

enum ViewAction as int
member Close:=1
member Open:=0
member Update:=2
end enum

end namespace //----- WpfMVLstartVN -----

=========================================================================================

//----- Product.prg -----
#using System
#using System.Collections.Generic
//----- added for LINQ -----
#using System.Data.Linq.Mapping //----- needed for Table & Column .....
#using System.Collections.ObjectModel //----- ObservableCollection .....
#using System.ComponentModel //----- INotifyPropertyChanged .....

BEGIN NAMESPACE WpfMVLstartVN

[Table(Name:="Products")];
class Product
//----- Fields -----
private _cost as real8
private _dateAdded as System.Nullable<System.DateTime>
private _description as string
private _name as string
private _price as real8
private _productId as Long
private _type as string

//----- Events -----
Event PropertyChanged AS System.ComponentModel.PropertyChangedEventHandler

//----- Constructors -----
constructor();super()
//
self:ProductId := -1

constructor(cN as string, cD as string, cT as string, nC as real8, nP as real8, dtA as System.Nullable<System.DateTime>);super()
//
self:ProductId := -1
self:Name := cN
self:Description := cD
self:@@Type := cT
self:Cost := nC
self:Price := nP
self:DateAdded := dtA

//----- Methods -----
static method GetProductCollection() as System.Collections.ObjectModel.ObservableCollection<Product>
return System.Collections.ObjectModel.ObservableCollection<Product>{Product.GetProductsList()}

static method GetProductsList() as System.Collections.Generic.List<Product>
local aList as List<Product>
aList := List<Product>{}
aList:Add(Product{"Long stand 19", "Holder for long pouch 19", "stand", 17.03, 19.73, System.DateTime{2001, 1, 1}})
aList:Add(Product{"Short stand 19", "Holder for long pouch 19", "stand", 15.23, 17.52, System.DateTime{2003, 3, 3}})
aList:Add(Product{"Extra long stand 19", "Holder for long pouch 19", "stand", 21.27, 24.09, System.DateTime{2002, 2, 2}})
aList:Add(Product{"Narrow pouch 19", "Pouch 19", "bag", 1.35, 2.45, System.DateTime{2004, 4, 4}})
aList:Add(Product{"Standard pouch 19", "Pouch 19", "bag", 1.45, 2.19, System.DateTime{2006, 6, 6}})
aList:Add(Product{"Wide pouch 19", "Pouch 19", "bag", 1.55, 2.56, System.DateTime{2008, 8, 8}})
aList:Add(Product{"Extra wide pouch 19", "Pouch 19", "bag", 1.65, 2.81, System.DateTime{2010, 10, 10}})
aList:Add(Product{"Dry Storage", "Small", "box", 1.05, 1.9, System.DateTime{2005, 5, 5}})
aList:Add(Product{"Dry Storage", "Medium", "box", 1.35, 2.08, System.DateTime{2007, 7, 7}})
aList:Add(Product{"xxxDry Storage", "xxMedium", "xbox", 1.35, 2.08, DateTime{2003, 4, 5}} )
return aList

method NotifyPropertyChanged(propertyName as string) as void
if (self:PropertyChanged != null)
self:PropertyChanged:Invoke(self, System.ComponentModel.PropertyChangedEventArgs{propertyName})
endif
return

//----- Properties -----
property Cost as real8
get
return self:_cost
end get
set
self:_cost := value
self:NotifyPropertyChanged("Cost")
end set
end property

property DateAdded as System.Nullable<System.DateTime>
get
return self:_dateAdded
end get
set
self:_dateAdded := value
self:NotifyPropertyChanged("DateAdded")
end set
end property

property Description as string
get
return self:_description
end get
set
self:_description := value
self:NotifyPropertyChanged("Description")
end set
end property

property Name as string
get
return self:_name
end get
set
self:_name := value
self:NotifyPropertyChanged("Name")
end set
end property

property Price as real8
get
return self:_price
end get
set
self:_price := value
self:NotifyPropertyChanged("Price")
end set
end property

property ProductId as long
get
return self:_productId
end get
set
self:_productId := value
self:NotifyPropertyChanged("ProductId")
end set
end property

property @@Type as string
get
return self:_type
end get
set
self:_type := value
self:NotifyPropertyChanged("Type")
end set
end property

end class //----- Product -----

end namespace //----- WpfMVLstartVN -----

=========================================================================================

//----- Supplier.prg -----

#using System
#using System.Collections.Generic
//----- added for LINQ -----
#using System.Data.Linq.Mapping //----- needed for Table & Column .....
//==================================
#using System.Collections.ObjectModel //----- ObservableCollection .....
#using System.ComponentModel //----- INotifyPropertyChanged .....

BEGIN NAMESPACE WpfMVLstartVN

[Table(Name:="Suppliers")];
class Supplier
// Fields
private _contactPerson as string
private _dateAdded as System.Nullable<System.DateTime>
private _email as string
private _phone as string
private _proximity as string
private _reliable as System.Nullable<Logic>
private _supplierId as Long
private _supplierName as string
private _type as string

// Events

Event PropertyChanged AS System.ComponentModel.PropertyChangedEventHandler

// Methods
constructor();super()
//
self:SupplierId := -1

constructor(cSN as string, dtAdd as System.DateTime, cCP as string, cPX as string, cT as string, lR as System.Nullable<Logic>, cPh as string, cE as string);super()
//
self:SupplierId := -1
self:SupplierName := cSN
self:DateAdded := System.Nullable<System.DateTime>{dtAdd}
self:ContactPerson := cCP
self:Proximity := cPX
self:@@Type := cT
self:Reliable := lR
self:Phone := cPh
self:Email := cE

static method GetSupplierCollection() as System.Collections.ObjectModel.ObservableCollection<Supplier>
//
return System.Collections.ObjectModel.ObservableCollection<Supplier>{Supplier.GetSuppliersList()}

static method GetSuppliersList() as System.Collections.Generic.List<Supplier>
//
local aList as List<Supplier>
aList := List<Supplier>{}
aList:Add(Supplier{"Sproutting Veg.", System.DateTime{2007, 9, 11}, "Hannah Handson", "Local", "Green Goods", true, "02920 1237000", "..."})
aList:Add(Supplier{"Feeling Good Healthcare",System.DateTime{2005,03,05} , "Jim Smith", "Local", "Health Stuff", true, "01633 234765", "..."})
aList:Add(Supplier{"Brown Box", System.DateTime{2006, 11, 19}, "Sally Brown", "Next County", "Boxes", false, "02920 122765", "sally@brownbox.co.uk"})
return aList

method NotifyPropertyChanged(propertyName as string) as void
//
if (self:PropertyChanged != null)
//
self:PropertyChanged:Invoke(self, System.ComponentModel.PropertyChangedEventArgs{propertyName})
endif

//----- Properties
property ContactPerson as string

get
//
return self:_contactPerson
end get
set
//
self:_contactPerson := value
self:NotifyPropertyChanged("ContactPerson")
end set
end property
property DateAdded as System.Nullable<System.DateTime>

get
//
return self:_dateAdded
end get
set
//
self:_dateAdded := value
self:NotifyPropertyChanged("DateAdded")
end set
end property
property Email as string

get
//
return self:_email
end get
set
//
self:_email := value
self:NotifyPropertyChanged("Email")
end set
end property
property Phone as string

get
//
return self:_phone
end get
set
//
self:_phone := value
self:NotifyPropertyChanged("Phone")
end set
end property
property Proximity as string

get
//
return self:_proximity
end get
set
//
self:_proximity := value
self:NotifyPropertyChanged("Proximity")
end set
end property
property Reliable as System.Nullable<Logic>

get
//
return self:_reliable
end get
set
//
self:_reliable := value
self:NotifyPropertyChanged("Reliable")
end set
end property
property SupplierId as Long

get
//
return self:_supplierId
end get
set
//
self:_supplierId := value
self:NotifyPropertyChanged("SupplierId")
end set
end property
property SupplierName as string

get
//
return self:_supplierName
end get
set
//
self:_supplierName := value
self:NotifyPropertyChanged("SupplierName")
end set
end property
property @@Type as string

get
//
return self:_type
end get
set
//
self:_type := value
self:NotifyPropertyChanged("Type")
end set
end property

end class

END NAMESPACE //----- WpfMVLstart

=========================================================================================

PHH - 19th. November 2013.


Converting a C# app into a Vulcan 3 app

Converting a C# app into a Vulcan 3 app

Converting a C# app into a Vulcan 3 app

 Previous topic Next topic

PHH - 19th. November 2013.


Appendix A - special characters in XAML

Appendix A - special characters in XAML

Appendix A - special characters in XAML

Previous topic Next topic

===========================================================================================

=========================================================================================================

PHH - 31st. October 2013.


Appendix B - tips and tricks - using VS 2012

Appendix B - tips and tricks - using VS 2012

Appendix B - tips and tricks - using VS 2012

 Previous topic Next topic

Missing and Adding - directives for 'using' :

[ .. VS 2012 .. ]

========================================================================================================================

================================================================================================

===================================================================================================================

============================================================

=================================================================

[ .. VS 2010 .. ]

=======================================================================================

Copy and Paste - references - one solution project to another :

Even across instances of VS 2012.

Copy From (Nick's) :

==================================================

Paste To (our's) :

=====================================================

Even Locally - "user made" Namespaces in Directives :

=======================================================================================================================

==========================================================================

PHH - 10th. November 2013.


Appendix C - PCL - Portable Class Library

Appendix C - PCL - Portable Class Library

Appendix C - PCL - Portable Class Library

 Previous topic Next topic

PHH - 15th. November 2013.


Appendix D - dateTime - various formats

Appendix D - dateTime - various formats

Appendix D - dateTime - various formats

 Previous topic Next topic

http://www.geekzilla.co.uk/View00FF7904-B510-468C-A2C8-F859AA20581F.htm

=======================================================================================================================================================

A part working solution - see below :((

======================================================================================

======================================

To get a fuller approach to handling 'null's and displaying text values see the child sub-folder of this one.

===========================================================================================================================

PHH - 16th. November 2013.


Handling 'null' and converting to Text

Handling 'null' and converting to Text

Handling 'null' and converting to Text

 Previous topic Next topic

=========================================================

========================================================================================================================================

For Vulcan Guys :-

*** WARNING *** 'null' has to be replaced in Vulcan code / syntax - we need the following :-

===========================================================================================================================

=====================================================================================================================================================================================

Let us now continue ...................

==============================================================================

PHH - 16th. November 2013.


Appendix E - DispatcherTimer and UI display

Appendix E - DispatcherTimer and UI display

Appendix E - DispatcherTimer and UI display

 Previous topic Next topic

PHH - 20th. November 2013.


Appendix F - UI updates OK, 'loop task', on secondary Thread

Appendix F - UI updates OK, 'loop task', on secondary Thread

 Previous topic This is the last topic

Appendix F - UI updates OK, 'loop task', on secondary Thread

 Previous topic This is the last topic

Below is a web link which started the investigation :-

http://stackoverflow.com/questions/5504244/how-do-i-refresh-visual-control-properties-textblock-text-set-inside-a-loop

Let us follow this through and find out a few things ...............

Problem Defined :

If we set a coded loop running on the main (UI) thread and try to update a property which

is bound to a XAML element attribute, the window / form / page does not update until after

the loop is finished. This is NOT what many of us guys wish :((

Here is a sample loop :-

=====================================================

In the above image the property 'MyValue' is the one bound to the UI control - see below :-

=================================================================================================

Basically, we can copy this suggested approach to a number of related instances of this type of situation.

The crux of the matter is in the next code image - see below :-

==============================================================================

As seen above, if the loop is made into a Task on a secondary (subsequent?) thread then

the UI thread is not held up, and any change in property can then be immediately reflected in the form

or window.

Lets try this with Dick's example problem :

If we make a new method to add into our Supplier (test) ViewModel code we see this :-

===============================================================

At app launch time we can run this method from the Constructor in the VM class - see below :-

========================================================================

We need to refresh our minds about the property used called 'Dick_Tock_Out' and so we

see this shown in the next image :-

=====================================================================

Note that the notification is sent from the property update - SO - we must in our code

[ .. line 197 way above .. ]

update the property and not the field, or no notification will be sent at all.

Here is a snapshot of the app running - all controls are active and available for our mouse

and touch :-

==================================================

And finally, we need to check out the XAML script to see the binding that is 'on' the

TextBlock being used for displaying purposes :-

================================================================================

So we should be able to have many loops running on secondary threads - I have an idea.

Go to see the earlier sub-section on 'Sliders' .....................

PHH - 21st. November 2013.