Archive

Posts Tagged ‘Properties’

Suggestion: C# static extension methods invokable on class type too

it would be nice if C# supported syntax like:

public static DependencyProperty Register(static DependencyProperty x, string name, Type propertyType, Type ownerType, FrameworkPropertyMetadata typeMetadata)

that is static extension methods for classes, that can be invoked without a class instance (just with the class type), apart from normal extension methods that can be invoked on a class instance.

Then for example I could use it in Silverlight to add to its DependencyProperty class some extra WPF syntax that it currently misses, in order to increase code portability. It would wrap Dr.WPF’s implementation of value coercion for Silverlight’s DependencyProperty. I have the related code at my Compatibility library (http://Compatibility.codeplex.com) and respective NuGet package (http://nuget.org/packages/Compatibility), but the syntactic sugar is missing to achieve source code portability (via WPF and Silverlight projects that include common files via file links) without changes.

Note the "static DependencyProperty" parameter instead of the "this DependencyProperty" one that is used in C# extension methods (or else instead of static maybe they could use other keyword like type or typeof there, but I feel static is more appropriate).

Related discussion:

http://stackoverflow.com/questions/866921/static-extension-methods

http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class

Also see https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f where somebody mentions "static extension properties" apart from "extension properties". Indeed it is natural that if static extension methods are to be allowed in the future, static extension properties should be added too (to extend a type with [attached] static properties)

You can vote for a related suggestion here:

https://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/2060313-c-support-static-extension-methods-like-f

Difference between LocalizableAttribute and LocalizabilityAttribute in .NET

I’ve just updated an older answer of mine at:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/716ef041-0a59-4c1d-9519-e14db4de7e75/localizability-vs-localizable-attributes-in-control-dev?forum=wpf

In case you’re wondering too what’s the difference between Localizable and Localizability attributes in .NET, maybe this helps a bit:

https://msdn.microsoft.com/en-us/library/ms753944(v=vs.100).aspx 

Seems the Localizability attribute is BAML-specific and makes sure localization-related comments (probably to make use by localization tools and show to the translators) are preserved/exposed when WPF XAML is compiled from text XML form into binary BAML.

Suggestion: property and event setting block attached to C# type instance

Instead of having to write in C#

      speechRecognizer = CreateSpeechRecognizer();
      if (speechRecognizer != null)
      {
        speechRecognizer.SomeProperty = someValue;
        speechRecognizer.SomeOtherProperty = someOtherValue;
        speechRecognizer.SpeechRecognized += SpeechRecognized;
        speechRecognizer.SpeechHypothesized += SpeechHypothesized;
        speechRecognizer.SpeechRecognitionRejected += SpeechRecognitionRejected;
      }

I’d prefer to write:

      speechRecognizer = CreateSpeechRecognizer() {
        SomeProperty = someValue,
        SomeOtherProperty = someOtherValue,
        SpeechRecognized += SpeechRecognized,
        SpeechHypothesized += SpeechHypothesized,
        SpeechRecognitionRejected += SpeechRecognitionRejected
      }

that is after any Type I’d like to be able to add {…} block with assignments to its properties, like I can do when I create a new type.

Do note that I also would like this syntax and the existing new Type(…) {…} syntax (which is a subset of this one) to support assignment and removal of event handlers, not just setting of properties, as shown in the example above

If you like this suggestion, vote it up at:

http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/9479250-property-and-event-setting-block-attached-to-c-ty

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: