How to make Resharper resolve path for CustomBinding MarkupExtension
Asked Answered
X

3

61

I want to create some extended Binding-Markup-Extension, which behaves just like a normal WPF-Binding but does some things more (use different defaults, maybe add some behavior, etc.). Code looks like this:

public class CustomBindingExtension : Binding
{
  .. some extra properties and maybe overrides ...
}

It all works fine including XAML-intellisense, except I just can't make Resharper resolve my Binding-Path correctly. I.e.: using this code I can [Strg]+Click on 'CurrentText' and Resharper lets vs2010 navigate to the code defining the CurrentText-Property.

<UserControl x:Name="uc" ...>
  <TextBox Text="{Binding ViewModel.CurrentText, ElementName=uc}" />
</UserControl>

But using my binding, which works correctly at runtime, I just get a Tooltip when hovering 'CurrentText' telling me it is some 'MS.Internal.Design.Metadata.ReflectionTypeNode', and no navigation via [Strg]+Click.

<UserControl x:Name="uc" ...>
  <TextBox Text="{util:CustomBinding ViewModel.CurrentText, ElementName=uc}" />
</UserControl>

I tried the following things:

  • Derive from Binding
  • Derive from BindingDecoratorBase
  • Leave out the 'Extension' suffix for my CustomBinding-class
  • put the Markup-Extension in a separate assembly
  • Use ConstructorArgumentAttribute
  • Property of type string and type PropertyPath for the Path-Property
  • I also looked at the original classes Binding and BindingBase, but could not find any more difference to my code. Any ideas what should help here? Or is this just a special treatment of the Binding-MarkupExtension which I can in no way get for my own MarkupExtensions?

    Update 16.03.2011: Might also be bug or deficiency of Resharper, Jetbrains is investigating the issue: http://youtrack.jetbrains.net/issue/RSRP-230607

    Update 10.12.2013: Meanwhile, the feature seems to be working (with R# 7.1.3, maybe also earlier versions), I actually use the approach with the BindingDecoratorBase and I like it a lot. Maybe it only works, if your MarkupExtension ends on 'Binding', but mine does, so I am happy.

    Xenon answered 10/3, 2011 at 20:7 Comment(4)
    I didn't even know you could do that. When I try it (with a regular Binding) I always get the behavior you get when you use the CustomBinding. Anything special I should do in order to get it working?Shieh
    Yeah, Ctrl+Click on CurrentText just selects the word for me. Are you sure that's not an extension that is jumping to the definition? Maybe the Productivity Power Tools?Colossus
    Ok, I was not sure about that, seems to be a Resharper-feature. Of course it only works if you are binding to something type-safe like the ViewModel and not the DataContext.Xenon
    It is a feature from Resharper, I will clarify this in the question.Xenon
    L
    4

    Actually it's not possible in current versions of R# and, unfortunately, still be missing feature of upcoming R# 6.1 release.

    This feature requires a lot of infrastructure changes, but it's on our list and definitely will be implemented in R# 7. Seems like [CustomBindingMarkup] and [BindingPath] (for path constructor parameter and the Path property) attributes will be introduced.

    We really apologize for any inconvenience.

    Launcher answered 25/10, 2011 at 10:44 Comment(3)
    +1 This would be a really helpful feature.... hopefully it will make it in to Resharper 7.0Rusel
    I have Resharper 7.1 installed and I'm still seeing this issue. Is this fix implemented yet and is there any documentation for how to enable it?Misprision
    Are there any news on further implementation plans?Botanical
    C
    1

    You should access your custom Markup-Extension, using the correct namespace:

    <UserControl x:Name="uc" ...
    xmlns:ext="clr-ns:YourProjectNamespace">
      <TextBox Text="{ext:CustomBinding ViewModel.CurrentText, ElementName=uc}" />
    </UserControl>
    

    Here is a nice article about creating custom Markup-Extensions.

    Carducci answered 23/10, 2011 at 12:40 Comment(1)
    Yeah, that's right. I corrected my code sample. Unfortunately, it does not solve the actual problem, in my tests I had the namespace in the xaml, otherwise the whole thing had failed to compile.Xenon
    T
    1

    One way to fool R# is to name it Binding:

    public class Binding : MarkupExtension
    {
        public Binding()
        {
        }
    
        public Binding(string path)
        {
            Path = path;
        }
    
        public string Path { get; set; }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return 5;
        }
    }
    

    Then it works the same as standard binding with R#

    <TextBlock Text="{custom:Binding SomeProp}" />
    
    Topper answered 18/12, 2014 at 22:57 Comment(0)

    © 2022 - 2024 — McMap. All rights reserved.