x:Static works as element but not as attribute with statics from project?!?
-
domenica 17 settembre 2006 20:16
I'm running Vista RC1 and playing with x:Static in elements and attributes and noticed a behavior that I'm not sure if it is by design or not. Here's the minimal repro:
Start with a Window and let's use a static from the system as its title, using attribute syntax. (The static can come from any referenced assembly in this case, just not from the assembly being compiled):
Window x:Class="XamlTests.Window1"<
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
Title="{x:Static Member=s:Environment.CommandLine}"
>
</Window>This complies and works just as expected, showing the command line in the title of the window. While interesting, this is pretty much useless, so I want to show a string of my own, following the same static pattern, since I don't want to hardcode that string in the XAML as it will be calculated at runtime. For that, I create a static class with the static property:
XamlTestsnamespace
{
public static class StaticData
{
public static string Hello { get { return "Hello World"; } }
}
}Then I reference this as my title, with the proper namespace changes:
<Window x:Class="XamlTests.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:XamlTests;assembly=XamlTests"
Title="{x:Static Member=c:StaticData.Hello}"
>
</Window>However, this fails to compile with this error:
Window1.xaml(6,5): error MC3050: Cannot find the type 'StaticData'. Note that type names are case sensitive.
Bummer! Does that mean that I can't use my own statics in XAML attributes? That doesn't seem right. On the other hand, if I use element syntax instead of attribute syntax it works, which makes the bug even more interesting:
Window x:Class="XamlTests.Window1"<
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:XamlTests;assembly=XamlTests"
>
<Window.Title>
<x:Static Member="c:StaticData.Hello"/>
</Window.Title>
</Window>The end result is exactly what I want and the only downside is the extra markup to get it done.
Sounds like a bug that the compiler can resolve the static call in elements but not in attributes.
The other bummer is that only public classes/methods can be used with x:Static. If the static I want happens to be from the VS-generated Resources.resx file, that class is internal by default and XAML will barf that it is not public.
Tutte le risposte
-
lunedì 18 settembre 2006 17:09
Since the "c:" namespace is a reference to the local assembly -- that is, StaticData and Window1 are both in XamlTests.exe -- you don't need to specify the assembly name on the clr-namespace xmlns. So this works for me:
<Window x:Class="XamlTests.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:XamlTests"
Title="{x:Static Member=c:StaticData.Hello}" >The behavior still looks like a bug, so we'll investigate, but in the mean time it can simplify your markup.
It should be possible to reference internal types as well. For example here, I made the StaticData internal. Are you only seeing a problem when it's in the Resources.resx file?
-
martedì 26 settembre 2006 05:45
Cool, that worked as long as the property is public, even if the class itself is internal.
With the class generated by the resx it doesn't work because the tool-generated property is also internal. If I manually make the property public then it works, but there's no such option in the resx visual designer. Resgen itself has /publicClass but that option is not exposed in the VS project for resx files.

