Pixata Custom Controls
For Lightswitch

Recent Posts

Popular tags (# posts in brackets)

Anonymous types (3) ASP.NET (5) C# (3) C# tricks and tips (2) Computers (6) Design patterns (3) DomainDataSource (3) Dynamic data (4) Entity framework (3) Entity model framework (5) F# (3) LightSwitch (12) Linq (6) Microsoft (2) MVP (2) MVVM (2) Project Euler (2) RIA services (5) Silverlight (2) SQL Server (4) Unit testing (4) Visual Studio (7) WCF (3) WPF (3)

Gratuitous link to StackExchange

Archives


Categories


Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Actually, as I'm self-employed, I guess that means that any views I expressed here aren't my own. That's confusing!


Acknowledgments

Theme modified from one by Tom Watts
C#/F# code styling by Manoli (for posts pre-2016) and Google code prettify (for post from Jan 2016 and beyond)


My rambling thoughts on exploring the .NET framework and related technologies

Whilst working on a new version of one of the main windows in an application, I ended up dumping loads of small jobs onto one of the other developers, as he was the main one working on the XAML file for the window, and if we both tried to edit the file, we ended up with conflicts.

After dumping the umpteenth extra job on him, I was trying to work out if there is a way I could ease his burden a little. There had been quite a few new issues where the extent of my involvement had been to modify the database and update the model. After that, I had to pass it over to him, to avoid us stomping on each other when working on the same files.

So, I got to wondering if there was any way we could split the new quote window up, so multiple people could work on it at the same time. I immediately rejected using user controls for parts of the window, as this has been a road to complexity that we've trodden before, and I for one really don't want to go down the route of handling multiple view models again. It gets too messy and complex. You know me, I'm a simple sort!

So, I looked into including XAML fragments, but gave up on that as a lost cause. I'm not the only one to want it, but it looks like no-one has successfully done it yet, at least, not without some scary code.

The next idea was to store some of the XAML as control templates in a resource dictionary. You don't want to go there, believe me!

However, the brain cell woke up around this point, and I contemplated using user controls, but sharing one view model between them. Unsure of how neat this would be, I tried it out, and was pleasantly surprised by something actually very obvious. My initial thought was to declare the view model as the DataContext for each control, but that led to problems with multiple instances of the view model, so was quickly abandoned.

However, a light bulb went on at this point, and I realised I was making it too complex.

When you add a control to your XAML, it automatically inherits the DataContext of its parent. This is true of user controls as well as built-in controls. What this means is that you can have a window whose DataContext is set as usual, then have user controls for bits of the window, don't have a separate view model for them, and don't set a DataContext on them at all. They will automatically inherits the DataContext of whatever is above them, enabling you to work as usual. This allows you to use the same view model for all user controls on the window.

This means that we could hive out various sections of the XAML into separate user controls, enabling me to work on one, and him to work on another. See the attached sample project, where I did just this. As you can see, if you click the button to show the rather simple quote window, the window itself and both user controls are using the same view model (check the hashcode shown in three places), and if you open another window, it uses its own view model. Download ShareViewModel.zip.

Quite amazing, but quite obvious when you think about it. It has a huge potential for simplifying many of our XAML files, which are often far too big to be manageable anyway.

We would have to be careful about naming and placing all of these user controls, to make sure we don't end up wasting time trying to find them all. I suggested that a VrtQuoteDetailsWindow.xaml would have a VrtQuoteDetailsWindowKeyInfoUserControl.xaml, a VrtQuoteDetailsWindowSomethingElseUserControl.xaml and so on, and that these should be stored in the same folder as the VrtQuoteDetailsWindow.xaml file. Yes, this moves away from the convention of splitting windows and user controls, but my personal opinion is that this is somewhat arbitrary anyway, and no great loss. I much prefer to keep related .xaml files together, irrespective of whether they are windows or user controls.

In order to keep the user controls together with the parent window, they should be nested. Whilst this can be done manually, it's slow and painful, and very easy to get wrong, which mucks up your project file and causes Visual Studio to have a hissy fit. Thankfully, someone has been kind enough to write a very neat extension, which enables you to nest files quickly and easily. Once you have it installed, you right-click on the file(s) that is/are to be a child(ren), and choose File Nesting -> Nest Item from the context menu (or just click Ctrl-Alt-N if you like keyboard shortcuts). This will pop up a small window, which will show you all the other files in the same folder...

Pick one and click the OK button. This will then nest the file(s) under the parent, leaving a neat structure. You can select multiple files, and nest them all under one parent in one go, which is nice.

As you can see, this worked very nicely for the quote window...

We were then able to work on separate parts of the same window, with a minimal amount of conflicts.

This then left the question of how to handle the view model, as we would still only have one of those. However, I have previously solved this problem by splitting the view model into several files. I had previously split another view model across four separate files, which makes it much easier to handle...

This is pretty easy to do. I was working with a class named VRTSystemsListViewModel. In such a case, you would add a new class to the same folder, and name it (say) VRTSystemsListViewModel_Commands. Then change the file name to VRTSystemsListViewModel.Commands.cs, and the class name to VRTSystemsListViewModel (making it partial of course). Then, you need to nest the child view model files under the parent (see above for those with an extremely short memory).

Note that the systems list view model was split into separate files for commands, INPC properties, messages, etc. On reflection, this wasn't the best way to do it, partly because it leaves related code spread over multiple files, and partly because it increases the chances of conflicts. If they had been split according to functionality, then we would have had the same benefits as explained earlier. I later did this for the system details window view model...

As you can see, the view model has been split according to features, making it less likely that two people would be working on the same files at the same time.

There was an unexpected side benefit to this idea. If you've spent any amount of time twiddling your thumbs while Visual Studio loads or saves a XAML file, you'll know how frustrating this is.

It's known issue with Visual Studio, which Microsoft have never acknowledged, and will presumably never fix. However, by splitting the XAML as described above, we dramatically reduced the amount of time Visual Studio spent thinking about loading and saving the XAML files. That made us happy

Thursday, 18 February 2016 17:00:00 (GMT Standard Time, UTC+00:00)

I had the need today to add my own property to a WPF user control, and have that property available in the Properties panel of the Visual Studio designer, so the property could be set at design-time. The purpose of this was that my user control had a toolbar, and I had come across the need to use the control, but not show the toolbar. Simple eh? Well, not quite!

My first thought was to add a normal C# property, but this didn’t show up in the Properties panel, so was quickly rejected.

I then came across this forum thread that showed how to add a Dependency property, which seemed to be what I needed. The property showed up in the Properties panel as required, but changing it didn’t affect the display of the toolbar.

It turns out that the static Dependency property cannot change properties of the non-static controls on the user control. You seem to need to call a non-static method to do that. I ended up with rather more code than I would have expected for such a simple task, but it looked like this…

   1:  public static readonly DependencyProperty ShowToolbarProperty 
   2:        = DependencyProperty.Register("ShowToolbar", typeof(bool), typeof(Cameras),
   3:                  new FrameworkPropertyMetadata(new PropertyChangedCallback(AdjustControl)));
   4:   
   5:  public bool ShowToolbar {
   6:    get {
   7:      return (bool)GetValue(ShowToolbarProperty);
   8:    }
   9:    set {
  10:      SetValue(ShowToolbarProperty, value);
  11:    }
  12:  }
  13:   
  14:  private static void AdjustControl(DependencyObject source, DependencyPropertyChangedEventArgs e) {
  15:    (source as Cameras).UpdateControls((bool)e.NewValue);
  16:  }
  17:   
  18:  private void UpdateControls(bool showToolbar) {
  19:    CamerasToolbar.Visibility = (showToolbar ? Visibility.Visible : Visibility.Collapsed);
  20:  }

Lines 1 to 3 declare the dependency property itself, passing the name of the actual property that we want to show up in VS (in this case ShowToolbar), the type of that property, the type of the containing control, and a rather nasty-looking callback to a method that would be called whenever the property was changed.

Lines 5-12 are the actual property we want, and are a fairly normal C# property declaration, except that they use GetValue() and SetValue() on the dependency property.

Lines 14-16 set up the static method that is called when the dependency property is changed. As explained above, as this is static, it can’t change the properties of controls, so we need to grab hold of the object that raised the event (in this case, the parent control), cast it to the correct type, call a non-static method and pass in the new property value.

Lines 18-20 simply set the Visibility property of the CamerasToolbar as required.

Quite a lot of code for such a simple task eh?

Thursday, 16 June 2011 15:59:00 (GMT Daylight Time, UTC+01:00)
# Tuesday, 22 February 2011

I was having some trouble with WPF data binding yesterday, where the binding looked correct, but the data wasn't being shown. It turned out that I had forgotten an .Include() on the original query (this data is being sent across the wire through a WCF service, so I can't use lazy loading), but along the way, I discovered a really useful blog post on how to debug WPF data binding.

Edit: After posting this entry, I noticed that one of the comments in the above blog post mentioned an older blog post that discussed the same subject. That adds a couple more ideas to the pot, so is worth reading as well.

Tuesday, 22 February 2011 14:06:13 (GMT Standard Time, UTC+00:00)