How to make Resharper resolve path for CustomBindi

2020-05-29 13:14发布

问题:

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.

    回答1:

    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.



    回答2:

    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.



    回答3:

    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}" />