Note that there are some explanatory texts on larger screens.

plurals
  1. POWPF MarkupExtension and RowDefinition results in NotImplementedException
    text
    copied!<p><strong>The scenario:</strong> Create a MarkupExtension to replace Grid.Row=”0” by Grid.Row=”{namespace:ClassExtension GridRowName}” (same for column)</p> <p><strong>Xaml Code:</strong></p> <pre><code>&lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="Auto" x:Name="TitleRow" /&gt; &lt;RowDefinition Height="Auto" x:Name="LastNameRow" /&gt; &lt;RowDefinition Height="Auto" x:Name="FirstNameRow" /&gt; &lt;RowDefinition Height="Auto" x:Name="EmailRow" /&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition x:Name="LabelColumn" /&gt; &lt;ColumnDefinition x:Name="ValueColumn" /&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;Label Grid.Row="{me:GridDefinition Name=TitleRow}" Grid.ColumnSpan="2" FontWeight="Bold" FontSize="14" /&gt; &lt;Label Grid.Row="{me:GridDefinition Name=LastNameRow}" Grid.Column="{me:GridDefinition Name=LabelColumn}" FontWeight="Bold" FontSize="14" /&gt; &lt;/Grid&gt; </code></pre> <p><strong>The requirement:</strong></p> <ul> <li>Show XAML Errors when an incorrent GridRowName (or columnName) is used </li> <li>Show no XAML errors when a correct GridRowName (or columnName) is used </li> <li>When a Valid ColumnName is used for a Row declaration (and vica verca) a XAML error should be shown</li> </ul> <p><strong>The problem:</strong> Everything works fine for Grid.Column, but Grid.Row always throws an “Not Implemented Exception” at designtime (grid.row is underlined, grid.column is not). <img src="https://i.stack.imgur.com/rQsIf.png" alt="enter image description here"></p> <p>The rows and columns are both named correct, but row always shows an error. If we specify an invalid column name, the column shows an error (which is expected, so Grid.Column works fine!) <img src="https://i.stack.imgur.com/grYZW.png" alt="enter image description here"></p> <p>As you can see, column works fine, but Rows don’t. The problem lies inside the MarkupExtension called GridDefinitionExtension:</p> <pre><code>[MarkupExtensionReturnType(typeof(int))] public class GridDefinitionExtension : MarkupExtension { public string Name { private get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { var referenceExt = new Reference(Name); var definition = referenceExt.ProvideValue(serviceProvider); if (definition is DefinitionBase) { var grid = (definition as FrameworkContentElement).Parent as Grid; if (grid != null &amp;&amp; definition is RowDefinition) return grid.RowDefinitions.IndexOf(definition as RowDefinition); if (grid != null &amp;&amp; definition is ColumnDefinition) return grid.ColumnDefinitions.IndexOf(definition as ColumnDefinition); } // This Extension only works for DefinitionBase Elements. throw new NotSupportedException(); } } </code></pre> <p>The Exception is trown on the line:</p> <pre><code>var definition = referenceExt.ProvideValue(serviceProvider); </code></pre> <p>After looking inside the DLL from which this method is called I have found that the body of this ProvideValue method looks like this:</p> <pre><code>public override object ProvideValue(IServiceProvider serviceProvider) { if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); IXamlNameResolver xamlNameResolver = serviceProvider.GetService(typeof (IXamlNameResolver)) as IXamlNameResolver; if (xamlNameResolver == null) throw new InvalidOperationException(System.Xaml.SR.Get("MissingNameResolver")); if (string.IsNullOrEmpty(this.Name)) throw new InvalidOperationException(System.Xaml.SR.Get("MustHaveName")); object obj = xamlNameResolver.Resolve(this.Name); if (obj == null) { string[] strArray = new string[1] { this.Name }; obj = xamlNameResolver.GetFixupToken((IEnumerable&lt;string&gt;) strArray, true); } return obj; } </code></pre> <p>I’ve simplified this ProvideValue method to only show the code which it is actually using in my scenario:</p> <pre><code>if (serviceProvider == null) throw new ArgumentNullException("serviceProvider"); IXamlNameResolver xamlNameResolver = serviceProvider.GetService(typeof(IXamlNameResolver)) as IXamlNameResolver; object obj = xamlNameResolver.Resolve(this.Name); if (obj == null) { var strArray = new string[1]{ this.Name }; obj = xamlNameResolver.GetFixupToken((IEnumerable&lt;string&gt;)strArray, true); } return obj; </code></pre> <p>Apparantly the Exception is thrown by the GetFixUpToken method, but the cause is the Resolve method. This Resolve method returns a valid object when lookup up the ColumnDefinition by its name, but it returns NULL when doing the exact same thing for a RowDefinition.</p> <p>The Error thrown by GetFixUpToken is: “NotImplementedException”, which is expected since when looking at the sourcecode of the IXamlNameResolver (which in this case is of Type: XamlNameResolverImpl)</p> <p><img src="https://i.stack.imgur.com/RhFuk.png" alt="enter image description here"></p> <p>When looking at the source code of this XamlNameResolverImpl, you can see that the method “GetFixUpToken” is empty and throws a NotImplemented exception (look at <a href="http://dotnetinside.com/en/framework/Microsoft+Expression/Microsoft.Expression.WpfPlatform/WpfMarkupExtensionValueSetter" rel="nofollow noreferrer">http://dotnetinside.com/en/framework/Microsoft+Expression/Microsoft.Expression.WpfPlatform/WpfMarkupExtensionValueSetter</a>)</p> <pre><code>public object GetFixupToken(IEnumerable&lt;string&gt; names, bool canAssignDirectly) { throw new NotImplementedException(); } public object GetFixupToken(IEnumerable&lt;string&gt; names) { throw new NotImplementedException(); } </code></pre> <p>But the problem is, as I already said, is the Resolve call, which works fine for columndefinition but fails for rowdefinitions…:</p> <p>Column: <img src="https://i.stack.imgur.com/UXFhZ.png" alt="enter image description here"></p> <p>Row: <img src="https://i.stack.imgur.com/Mcvny.png" alt="enter image description here"></p> <p>At this point, I don't know what to do anymore...</p> <p>Source code (example project) available at: <a href="http://www.frederikprijck.net/stuff/MarkupExtension.rar" rel="nofollow noreferrer">http://www.frederikprijck.net/stuff/MarkupExtension.rar</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload