Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

c# - d:DesignInstance with an interface type

I'm binding an UI to an interface (which is implemented by several presenters, not accessible from the UI assembly).

I really like d:DesignInstance in designer because it (kind of) makes xaml strongly typed using R#.

Sadly, d:DesignInstance does not support interface types: "Cannot create an instance of an interface."

Design instance on interface

The first thing I thought is: Ok, no problem, let's create a custom markup extension which takes a System.Type as parameter, and which ProvideValue method returns a fake instance of it (dummy implementation of this interface, generated by dynamic IL emission).

This works quite well, bindings are resolved at design-time (I can see that in the design panel since my markup extension fills the object properties with a lorem-ipsum)

BUT the nicest R# feature dont work: Resharper does not recognize datacontext type, and just gives a message "Cannot resolve property '{0}' in data context of type 'object'"

Custom markup extension

Does someone know how to fix this ?

(any alternative which would allow me to let R# know about an interface datacontext type would be great)

Thanks !

ps: I also tried to create another markup extension which returns the generated runtime type in order to give it to DesignInstance: "{d:DesignInstance Type={utilsUi:InstanceType commons:User}}" => Gives the error "Object of type 'InstanceType' cannot be converted to type 'System.Type'" ... seems that DesignInstance does not support inner markup extensions :(

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I've found out how it's possible to overcome this illogical Visual Studio XAML designer error.

Instead of

<SomeControl d:DataContext={d:DesignInstance commons:IUser}>
    <!--element content here-->
</SomeControl>

You can write

<SomeControl>
    <d:SomeControl.DataContext>
        <x:Type Type="commons:IUser" />
    </d:SomeControl.DataContext>
    <!--element content here-->
</SomeControl>

Yes, this solution doesn't look as cool but definitely it isn't much worse.

Type tag allows specifying interfaces, nested types (e.g. n:A+B) and even generics!

In case of generics just add a backtick and number of type arguments to your type: <x:Type Type="commons:User`1" />.

BTW all of these also works with styles, <d:Style.DataContext> doesn't produce errors!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...