Archive

Posts Tagged ‘Source’

Structuring (physical) source and (virtual) solution folders for portability

Copying here those comments of mine at a discussion on the GraphX project:

https://github.com/panthernet/GraphX/issues/21

describing the source code (physical) folder structure and the Visual Studio solution (virtual) folder structure I’ve been using at ClipFlair and other multi-platform projects.

——

looking at the folders/projects/libraries/namespaces naming, I think it would be more appropriate to add the platform at the end of the name, say GraphX.somePart.PCL, GraphX.somePart.UWA (=Universal Windows Application model [aka Win10]) etc. Not sure how easy it will be though for contributors to merge pending changes via GitHub if you do such drastic changes (I’m still struggling with Git myself, prefer Mercurial)

Speaking of moving the platform to the end of the name (e.g. GraphX.Controls.WPF, GraphX.Controls.SL5 etc.), to do it on the folder names (apart from doing at the source code for packages, target assemblies etc.), I think one has to use some Version Control command to "move" (Git should have something like that) the files to the new folder, else other contributors may have issue merging their changes.

Despite the trouble to do it, I think it is better for the long run. Also, all GraphX.SomePart.* subfolders could then be grouped in a GraphX.SomePart folder as subfolders where a Source or Common subfolder would also exists that has all the common code those platform-specific versions of GraphX.SomePart share (via linked files to ..\Common\SomeFile, ..\Common\SomeFolder\SomeFile and ..\Common\SomeOtherFolder\SomeFile etc.)

This is the scheme I’ve been using (and I’m very satisfied with) at http://clipflair.codeplex.com and other projects (e.g. at the AmnesiaOfWho game [http://facebook.com/AmnesiaOfWho] that has separate versions for SL5, WP7 and WP8 and WPF version on the works, plus WRT (WinRT) and UWA [Universal Windows App] too coming in the near future, with all code and most XAML shared via linked files and UserControl[s])

I meant I’d expect GraphX.Common folder with GraphX.Common.PCL in it and GraphX.Common.WP7 etc. versions for example also in that folder since PCL is usually set at WP8 level. This is just an example.

What I’m saying is that the platform name is the last part of the specialization chain, so logically GraphX comes first then say comes Controls then comes WPF, SL5, WP8 etc. in the folder name.

Also would have 3 parent folders Controls, Common and Logic. The last two would just contain the respective .PCL subfolder for now, but I can contribute subfolders for specific platforms too, esp for those the common PCL profile doesn’t cover. Source would be at Controls\Source, Common\Source, Logic\Source and respective platform specific projects (even the pcl projects) would use linked files

aka

GraphX (contains GraphX.sln)

–\Controls
—-\Source
—-\GraphX.Controls.WP7
—-\GraphX.Controls.WP8
—-\GraphX.Controls.SL5 (contains GraphX.Controls.SL5.csproj)
—-\GraphX.Controls.WPF (contains GraphX.Controls.WPF.csproj)
—-\GraphX.Controls.WIN8
—-\GraphX.Controls.UWA
—- … (more platform specific versions)

–\Common
—-\Source
—-\GraphX.Common.PCL
—- … (platform specific versions, esp. those not covered by the settings chosen at the PCL)

–\Logic
—-\Source
—-\GraphX.Logic.PCL
—- … (platform specific versions, esp. those not covered by the settings chosen at the PCL)

The same structure would also be used at examples to cover the potential of porting some of them to more platforms:

–\Examples
—-\SomeExample
——\Source
——\SomeExample.WPF
——\SomeExample.SL5
—-\SomeOtherExample
——\Source
——\SomeOtherExample.WIN8
——\SomeOtherExample.UWA
etc.

Of course common code at each folder is at the Source subfolder of that folder, shared using linked files (e.g. at \Examples\SomeExample\Source) and platform specific code is inside the respective projects (e.g. at \Examples\SomeExample\SomeExample.WPF)

Similarly the GraphX.sln would contain solution folders "Controls", "Common" and "Examples", though it could also contain separate solution (virtual) folders per platform that have each one of them "Controls", "Common" and "Examples" in them. That is the solution’s folder structure is organized per-platform in such a case. This is mostly useful if you want to focus on a specific platform each time when developing. However since the solution folders are virtual, one could even go as far as having two solutions, one with the same structure as the filesystem folders I suggest and one with a per-platform/target structure.

I follow the per-platform virtual solution folders style at ClipFlair.sln in http://clipflair.codeplex.com, while the real folders are structured as I describe above (where each module has its own physical subfolders for the various platforms). In fact some module subfolders there (say Client\ZUI\ColorChooser) contain their own extra solution file when I want to be able to focus just on a certain module. That solution just includes the respective ColorChooser.WPF, ColorChooser.SL5 etc. subprojects from respective subfolders). Such solutions also contain virtual WPF, Silverlight etc. subfolders that has as children apart from the respective platform-specific project (say ColorChooser.WPF) any other platform-specific projects needed (e.g. ….\Helpers\Utils\Utils.WPF\Utils.WPF.csproj etc.) by that module to compile.

Speaking of Xamarin, adding support for that too could follow the same pattern as described above (PCL where possible and platform-specific versions for .XamarinIOS, .XamarinAndroid etc. where needed)

Advertisements

Source code analyzers for .NET porting & Portable Class Libraries (PCL)

Gotcha: MediaElement Source=null releases stream, SetSource(null) fails

This is my contribution to:

http://stackoverflow.com/questions/19294258/forcing-mediaelement-to-release-stream-after-playback/27436323

If you use MediaElement, make sure you don’t get bitten by this one: http://msdn.microsoft.com/en-us/library/cc626563(v=vs.95).aspx

ArgumentNullException – The mediaStreamSource is null.

After calling this method, MediaElement.Source returns null. If this is called and MediaElement.Source is set, the last operation wins.

If a MediaElement is removed from the UI tree while is has an opened MediaStreamSource, subsequent calls to SetSource may be ignored. To ensure featureSetSource calls will work, set the Source property to null before detaching the MediaElement from the UI tree.

naturally one would expect, if they only use SetSource(somestream) to use SetSource(null) to release the resources. Nope, they thought "better", you have to use Source=null instead to release resources and SetSource(null) throws ArgumentNullException

that is what I call a design bug (breaks the rule of "least expected" behavior and causes bugs that bite you at runtime only [unless somebody has made a static analysis rule to catch such a thing – would need metadata of course that some argument can’t be null, like in Code Contracts])

I managed to introduce this bug while refactoring some code in ClipFlair Studio‘s AudioRecorder control the other day 😦

Note that you can’t use at MediaElement something like Source = stream to open a Stream, since that is a Uri property (not an Object property to also accept Stream) and you have to use SetSource(stream) instead, so you’d also expect to be able to use SetSource(null) to release the resources.

Update: Fixed this in AudioRecorderView class (uses MVVM pattern) of AudioRecorderControl, at Audio property’s "set" accessor it needed the following null-guarding pattern:

if (mediaStreamSource != null) 

  player.SetSource(mediaStreamSource); 
      //must set the source once, not every time we play the same audio, 
      //else with Mp3MediaSource it will throw DRM error

else

   player.Source = null;

HowTo: Code folding in NetBeans IDE source code editor

As explained near the end of https://ui.netbeans.org/docs/ui/code_folding/cf_uispec.html, the NetBeans IDE source code editor supports custom code folding tags for any language, like below (here defining the code folding tag in a Java comment, obviously need to use specific comment syntax for the respective language).

// <editor-fold desc="isUserStudent"> —————————————-

public static boolean isUserStudent(PortletRequest request)
   throws NamingException, PortletServiceUnavailableException,  PumaException, SQLException
{
   return isUserStudent(new DbAccess().getConnection(), request);
}

public static boolean isUserStudent(Connection connection, PortletRequest request)
   throws NamingException, PortletServiceUnavailableException,  PumaException, SQLException
{
   return !StringUtils.isNotPresent(getUserStudentId(connection, request));
}
 
public static boolean isUserStudent(int studentId, PortletRequest request)
   throws NamingException, PortletServiceUnavailableException,  PumaException, SQLException
{
   return isUserStudent(studentId, new DbAccess().getConnection(), request);
}

public static boolean isUserStudent(int studentId, Connection connection, PortletRequest request)
   throws NamingException, PortletServiceUnavailableException,  PumaException, SQLException
{
   return (String.valueOf(studentId).equals(getUserStudentId(connection, request)));
}
 
public static String getUserStudentId(Connection connection, PortletRequest request)
   throws NamingException, PortletServiceUnavailableException,  PumaException, SQLException
{
   return DbStudent.getStudentId(connection, Puma.getUserName(request)); 
}

// </editor-fold>————————————————————-

 

This shows up in NetBeans like below when folded:

image

You can also optionally specify defaultstate="collapsed" at the code folding tag so that when the file is opened that region appears collapsed.

Categories: Posts Tags: , , , , , , ,

Fix: Visual Studio opens class diagram in XML editor with double click

Recently, to save myself sometime after having renamed some interfaces/classes in the ClipFlair project sourcecode, I right-clicked one of the class diagrams (.cd files) in it at Visual Studio’s “Solution Navigator” (this is an enhanced Solution Explorer addon) and using “Open With…” I opened up the diagrams with the XML editor to do a rename-all operation for the respective class names.

However, after saving the project I found out that from then on, that specific .cd file was opening up as XML file when double-clicked instead of opening up as a Class Diagram in the respective designer pane. Using Open With dialog would open it as a Class Diagram when asked to specifically, but using the checkbox to always open up as Class Diagram wouldn’t help fix the double-click problem for that specific .cd file (others would open up fine as class diagrams, not as XML files, when double-clicked).

I just managed to fix that issue by right clicking the file node in solution navigator’s tree and and excluding that file from the project (not deleting!), then saving the project, closing the solution containg the project and adding the file (via “Add existing file”) again after having reopened the solution. I could also possibly have right clicked selected “Unload project” after saving it and then select to reload it again, think that would have worked too.

Using VisualHG addon for Visual Studio I commited the changes to the Mercurial repository used by ClipFlair on Codeplex, which showed me that the file difference that did the fix was the following in the .csproj project file:

   <ItemGroup>
     <None Include="Diagrams\Windows.cd" />
-    <None Include="Diagrams\Windows.Views.Interfaces.cd">
-      <SubType>Designer</SubType>
-    </None>
+    <None Include="Diagrams\Windows.Views.Interfaces.cd" />
     <None Include="Diagrams\Windows.Views.ViewModels.cd" />
   </ItemGroup>

 

That is instead of that marked-as-bold entry above (marked by the diff tool with – prefix), the line marked with + prefix should be used instead. This is obviously some bug in Visual Studio 2010, it’s nice to know though that you can easily take the project offline and edit the .csproj to fix it (or remove the .cd file, save the project, reload it and add the file again).

HowTo: Bind to a DataContext property named Source in XAML

While refactoring ClipFlair code to use MVVM (Model-View-ViewModel) pattern, I came across the XAML error “Object reference not set to an instance of an object.”, shown in Visual Studio when trying to bind to my ViewModel (accessed implicitly, being set as the DataContext of the XAML control) for a property named Source.

I have settled down to using the following MVVM-style pattern (of my own) at ClipFlair:

image

Update: Later on, at ClipFlair project, I renamed folder “Views” to “ViewModels” and folder “Components” to “Views” and moved “ViewModels” folder inside the “Views” one to keep view-related stuff in one place.

IImageViewer.cs:

image

ImageView.cs:

image

Update: Later on, I refactored this to initialize the fields directly instead of at the constructor:

//can set fields directly here or at the constructor     
private Uri source = IImageViewerDefaults.DefaultSource;

ImageViewerWindow.xaml.cs (the so-called codebehind for the XAML control):

image

Note above how we set the “DataContext” of the control to our ViewModel, so that we can bind to its properties implicitly (without referencing it) in the XAML.

Update: There’s something very important I had forgotten to do at the implementation of the “View” property in the code above, that is to listen for PropertyChangeEvents emitted by the ViewModel. In specific, we need to listen for changes of the ViewModel’s “Source” property to keep the View’s “SourceProperty” (a DependencyProperty that is also accessed via the View’s “Source” property) in sync with the ViewModel’s “Source” property. So the code shown in the above screenshot has to be fixed by changing the “View” property’s implementation like below:

image

For extra safety in case you want to allow setting a null ViewModel to the View property, you could check for (value != null) before trying to add PropertyChanged event handler to it:

if (value != null)

  value.PropertyChanged += new PropertyChangedEventHandler(View_PropertyChanged);

Obviously, if more DependencyProperties are added to the component (e.g. to be able to set them declaratively from XAML when instantiating the component) that have to be in sync to respective ones at the ViewModel (which is held by the View property), then the “View_PropertyChanged” method (event handler) implementation has to be extended with “else if” statements for each of those properties to set the respective dependency properties from the matching ViewModel properties.

BTW, if your ViewModel passes null to the changed property name to mark a single change event for multiple properties, then you have to also take that in mind (else you will get exception when you try to call “Equals” method on null string), by doing something like below:

if (e.PropertyName == null) {

Source = View.Source;

OtherProperty = View.OtherProperty;

//…sync all properties since we are not told which ones changed

return;

}

else if (e.PropertyName.Equals(“Source”) {

Source = View.Source;

}

else if (e.PropertyName.Equals(“OtherProperty”)

{

OtherProperty = View.OtherProperty;

}

//…

Note that instead of “.Equals” one could have also used “==” operator, since the C# compiler maps the string equality operator to string’s “.Equals” method.

Update: Another retouch I have since done to the code above is to avoid hardcoding property names and their default values and use nstead ithe proprerty name constants defined at the class IImageViewerProperties and the respective default values defined at IImageViewerDefaults. For example, I prefer to use (after adding a “using ClipFlair.Models.Views;” to the top):

public static readonly DependencyProperty SourceProperty =

DependencyProperty.Register(IImageViewerProperties.PropertySource, typeof(Uri), typeof(ImageWindow), new FrameworkPropertyMetadata(

(Uri)IImageViewerDefaults.DefaultSource,

new PropertyChangedCallback(OnSourceChanged)));

Update: I eventually opted for using a “switch” statement instead of nested if / else if statements, to keep things cleaner when more properties are added:

    protected void View_PropertyChanged(object sender, 
                                        PropertyChangedEventArgs e)
    {
       if (e.PropertyName == null)
       {
         Source = View.Source;
         //...
       }
       else switch (e.PropertyName)
           //string equality check in .NET uses ordinal (binary) comparison 
           //semantics by default
         {
           case IImageViewerProperties.PropertySource:
             Source = View.Source;
             break;
           //...
         }
     }

In an even newer iteration of that code, I removed the if/else and added the null check in the switch statement:

    protected void View_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
      switch (e.PropertyName) 
      {
        case null:
          Source = View.Source;
          //...
          break;
        case IImageViewerProperties.PropertySource:
          Source = View.Source;
          break;
        //...
       }
    }

ImageViewerWindow.xaml (the XAML control):

image

The issue at the last screenshot is that you can’t write Source=”{Binding Source}” as you’d write Source=”{Binding SomeDataContextProperty}”, but need to write Source=”{Binding Path=Source}” instead, since Source is a keyword at Binding expression syntax.

BTW, note that at the “edImageURL” TextBox I use Mode=TwoWay (two-way binding, the default is one way binding from source [the DataContext in our case] to target), whereas at the Image control I don’t. Both get an image URI from the ViewModel’s “Source” property, but we also want to be able to edit the URI at the textbox and update the view’s Source property (which will in turn update the Image control with the new image).

Also, note that apart from passing a URI to the Source property of an Image control there’s also a more verbose syntax one could use above, which can be handy to know of:

<Image>

<Image.Source>

<BitmapImage UriSource=”{Binding Path=Source}” />

</Image.Source>

</Image>

The <Image.Source> tag here is using the so-called property element syntax pattern. In the snippet above it sets a value to the Source property of the Image tag. XAML can use both XML attributes and child elements to set values to properties of controls, but whereas the attribute name would be “Source”, the child element tag has to be “Image.Source”, not just “Source”, since the XML schema needs to have unique definitions for the XML tags, whereas multiple objects could define different Source properties causing naming collisions.

According to http://10rem.net/blog/2012/03/27/tip-binding-an-image-elements-source-property-to-a-uri-in-winrt-xaml this more verbose syntax is needed at Windows 8 Metro-style apps (that is for the WinRT API) for binding an Image to a URI (but since that article is back from March 2012, probably this is not an issue any more).

%d bloggers like this: