Add MarkupExtension , x:Static, x:Type, RelativeSource FindAncestor #27

Open
andyb1979 opened this Issue May 11, 2017 · 13 comments

Comments

Projects
None yet
7 participants
@andyb1979

andyb1979 commented May 11, 2017

Without MarkupExtension, UWP is really really hard to develop controls for. See this thread for background.

I am the owner of SciChart - High Performance Realtime Charts. We make successful, big-data charts on WPF, iOS and Android platforms, and are close to releasing Xamarin.iOS and Xamarin.Android support.

We don't support UWP. The reason why is it is virtually impossible to port our existing XAML which depends heavily on the x:Static extension, RelativeSource FindAncestor, and various custom MarkupExtensions which enable our default themeing with binding fallbacks.

Example of code we want to replicate in UWP/Xaml Standard:

<Style x:Key="AnnotationBaseStyle" TargetType="a:AnnotationBase">    
    <Style.Setters>    
        <Setter Property="IsTabStop" Value="False" />    
        <Setter Property="Foreground" Value="{me:ThemeBinding TickTextBrush}" />    
        <Setter Property="FontSize" Value="12" />    
    </Style.Setters>    
</Style>

... where ThemeBinding is a class which inherits MarkupExtension.

<s3D:SciChart3DSurface x:Name="SciChart"
                               Grid.Column="1"
                               BorderThickness="0"
                               RenderableSeries="{extensions:SeriesBinding RenderableSeries}"
                               WorldDimensions="200,100,200">

            <s3D:SciChart3DSurface.XAxis>
                <s3D:NumericAxis3D AutoRange="Always" GrowBy="0.1,0.1" />
            </s3D:SciChart3DSurface.XAxis>

            <s3D:SciChart3DSurface.YAxis>
                <s3D:NumericAxis3D AutoRange="Always" GrowBy="0.1,0.1" />
            </s3D:SciChart3DSurface.YAxis>

            <s3D:SciChart3DSurface.ZAxis>
                <s3D:NumericAxis3D AutoRange="Always" GrowBy="0.1,0.1" />
            </s3D:SciChart3DSurface.ZAxis>

        </s3D:SciChart3DSurface>

... where SeriesBinding is a markup extension that enables a complex binding in our library.

Why is this so critical to us?

  • Without RelativeSource FindAncestor you have to resort to ugly hacks to bind to parts of the Visual Tree above the current element. See my answer on StackOverflow for guidance.

  • Without x:Static it is impossible to bind to a static class, e.g. a global property ThemeManager.EnableDropShadows cannot be bound and get updates from it as the property changes when someone sets it throughout the code.

  • Without MarkupExtension it is impossible to code our own replacement for x:Static or any other custom markup other than Binding, ThemeResource in UWP.

This means our only options are attached properties and custom parsing of complex strings. A nasty way to write xaml and we dont want to do it!

@h82258652

This comment has been minimized.

Show comment
Hide comment
@h82258652

h82258652 May 12, 2017

I hope they can bring back x:Static and DynamicResource.
But I dont think RelativeSource.FindAncestor is necessary. In most case you can use binding element name to do this, and FindAncestor performance is not good.

I hope they can bring back x:Static and DynamicResource.
But I dont think RelativeSource.FindAncestor is necessary. In most case you can use binding element name to do this, and FindAncestor performance is not good.

@stefanolson

This comment has been minimized.

Show comment
Hide comment
@stefanolson

stefanolson May 12, 2017

I have been on about this for years.. I feel like no one in Microsoft actually listens to people who have invested in WPF. I think find ancestor binding is absolutely critical. I've got a lot of code where find ancestor is the only way to make it work and therefore I can't port things to UWP. I'd also like to see multi-binding. there are scenarios where it is the best way to do things, although if x:Bind were supported in WPF that may be less of an issue.

stefanolson commented May 12, 2017

I have been on about this for years.. I feel like no one in Microsoft actually listens to people who have invested in WPF. I think find ancestor binding is absolutely critical. I've got a lot of code where find ancestor is the only way to make it work and therefore I can't port things to UWP. I'd also like to see multi-binding. there are scenarios where it is the best way to do things, although if x:Bind were supported in WPF that may be less of an issue.

@andyb1979

This comment has been minimized.

Show comment
Hide comment
@andyb1979

andyb1979 May 12, 2017

@stefanolson

This comment has been minimized.

Show comment
Hide comment
@stefanolson

stefanolson May 12, 2017

I definitely have examples where I've had to create thousands of lines of C# code to work around lack of find ancestor. It just makes things so much more complicated and messy.

I definitely have examples where I've had to create thousands of lines of C# code to work around lack of find ancestor. It just makes things so much more complicated and messy.

@andyb1979

This comment has been minimized.

Show comment
Hide comment
@andyb1979

andyb1979 May 12, 2017

@stefanolson have you seen my workaround for RelativeSource FindAncestor on UWP? It works but it's ugly.

That one was easy to code around but MarkupExtension, x:Static is not. I am considering to make attached properties where I pass in a completely un-type-safe string and parse it e.g.

Imagine I want to bind the Forground property statically to SomeType.Instance.SomeProperty.

I can theoretically achieve it in UWP with the most egregious hack. Creating a class with an attached property, that accepts a string which we parse to get the Target, the Source (static class) and the Path on the static path:

<!-- Workaround for x:Static in UWP ... -->
<Setter Property="MyStaticHelper" Value="TargetProperty=Foreground, StaticClass=SomeType, StaticPath=Instance.SomeProperty">
</Setter>

You can imagine the sorts of issues here. We have to write code like this and hope that it works at runtime as the strings are not type safe. Plus the internals of that MyStaticHelper is full of reflection. Slow and ugly and un-type-safe at the same time.

Of course, with MarkupExtension in UWP we can write our own Static, which I have done for Silverlight in the past.

I should clarify the actual real world examples of these are a lot more interesting and cannot be easily worked around by not using x:Static and MarkupExtension. We want to port a very large codebase (150,000 lines) from WPF -> UWP and Xamarin.Forms but are hampered by the lack of support for basic operations which were available in WPF in 2007.

andyb1979 commented May 12, 2017

@stefanolson have you seen my workaround for RelativeSource FindAncestor on UWP? It works but it's ugly.

That one was easy to code around but MarkupExtension, x:Static is not. I am considering to make attached properties where I pass in a completely un-type-safe string and parse it e.g.

Imagine I want to bind the Forground property statically to SomeType.Instance.SomeProperty.

I can theoretically achieve it in UWP with the most egregious hack. Creating a class with an attached property, that accepts a string which we parse to get the Target, the Source (static class) and the Path on the static path:

<!-- Workaround for x:Static in UWP ... -->
<Setter Property="MyStaticHelper" Value="TargetProperty=Foreground, StaticClass=SomeType, StaticPath=Instance.SomeProperty">
</Setter>

You can imagine the sorts of issues here. We have to write code like this and hope that it works at runtime as the strings are not type safe. Plus the internals of that MyStaticHelper is full of reflection. Slow and ugly and un-type-safe at the same time.

Of course, with MarkupExtension in UWP we can write our own Static, which I have done for Silverlight in the past.

I should clarify the actual real world examples of these are a lot more interesting and cannot be easily worked around by not using x:Static and MarkupExtension. We want to port a very large codebase (150,000 lines) from WPF -> UWP and Xamarin.Forms but are hampered by the lack of support for basic operations which were available in WPF in 2007.

@Mike-EEE

This comment has been minimized.

Show comment
Hide comment
@Mike-EEE

Mike-EEE May 19, 2017

FWIW, I've made a request on this UserVoice issue for the issue here to be the official GitHub equivalent for discussion and collaboration:

https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/7232264-add-markup-extensions-to-and-improve-winrt-xaml

FWIW, I've made a request on this UserVoice issue for the issue here to be the official GitHub equivalent for discussion and collaboration:

https://wpdev.uservoice.com/forums/110705-universal-windows-platform/suggestions/7232264-add-markup-extensions-to-and-improve-winrt-xaml

@andyb1979

This comment has been minimized.

Show comment
Hide comment
@andyb1979

andyb1979 May 19, 2017

@tomzorz

This comment has been minimized.

Show comment
Hide comment
@tomzorz

tomzorz May 19, 2017

// off
@andyb1979 it's not impossible to bind to a static without markup extensions in UWP: you can pull it off with some CustomResource magic
// /off

tomzorz commented May 19, 2017

// off
@andyb1979 it's not impossible to bind to a static without markup extensions in UWP: you can pull it off with some CustomResource magic
// /off

@andyb1979

This comment has been minimized.

Show comment
Hide comment
@andyb1979

andyb1979 May 19, 2017

@tomzorz

This comment has been minimized.

Show comment
Hide comment
@tomzorz

tomzorz May 19, 2017

@andyb1979 Don't get me wrong, I wholeheartedly agree that we need MarkupExtensions. Just wanted to point it out that it was possible if you really wanted ;)

tomzorz commented May 19, 2017

@andyb1979 Don't get me wrong, I wholeheartedly agree that we need MarkupExtensions. Just wanted to point it out that it was possible if you really wanted ;)

@birbilis

This comment has been minimized.

Show comment
Hide comment
@birbilis

birbilis May 19, 2017

MarkupExtensions were mentioned as being looked into for inclusion at XAML Standard at Build panel

MarkupExtensions were mentioned as being looked into for inclusion at XAML Standard at Build panel

@Mike-EEE

This comment has been minimized.

Show comment
Hide comment
@Mike-EEE

Mike-EEE May 19, 2017

MarkupExtensions were mentioned as being looked into for inclusion at XAML Standard at Build panel

Not so fast. Have you read the actual UserVoice comments lately? They are not even set on using IServiceProvider or any of the core/abundant/valuable services that are available in WPF and pretty much every flavor of Xaml out there. That hardly classifies as a MarkupExtension, I'm afraid.

So when a panel states that MEs are being included in the standard, what is the definition of an ME, exactly? This is a slightly important detail to get squared away.

(Also, thank you for your support, @andyb1979!)

MarkupExtensions were mentioned as being looked into for inclusion at XAML Standard at Build panel

Not so fast. Have you read the actual UserVoice comments lately? They are not even set on using IServiceProvider or any of the core/abundant/valuable services that are available in WPF and pretty much every flavor of Xaml out there. That hardly classifies as a MarkupExtension, I'm afraid.

So when a panel states that MEs are being included in the standard, what is the definition of an ME, exactly? This is a slightly important detail to get squared away.

(Also, thank you for your support, @andyb1979!)

@birbilis

This comment has been minimized.

Show comment
Hide comment
@birbilis

birbilis May 23, 2017

They probably care about the syntax at the XAML level, but may want to introduce some other implementation at the codebehind.

They probably care about the syntax at the XAML level, but may want to introduce some other implementation at the codebehind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment