1

Universal Store Project for 8.1 here.

I have a PathIcon declared in a ResourceDictionary like this:

<PathIcon 
    x:Key="PhoneIcon" 
    Data="F0 M22,22z M0,0z M17.4,22.533333C19.111111,25.955556,22.044444,28.766667,25.466667,30.6L28.155556,27.911111C28.522222,27.544444 29.011111,27.422222 29.377778,27.666667 30.722222,28.155556 32.188889,28.4 33.777778,28.4 34.511111,28.4 35,28.888889 35,29.622222L35,33.777778C35,34.511111 34.511111,35 33.777778,35 22.288889,35 13,25.711111 13,14.222222 13,13.488889 13.488889,13 14.222222,13L18.5,13C19.233333,13 19.722222,13.488889 19.722222,14.222222 19.722222,15.688889 19.966667,17.155556 20.455556,18.622222 20.577778,18.988889 20.455556,19.477778 20.211111,19.844444L17.4,22.533333 17.4,22.533333z"
    />

I can get this resource in code behind like this:

PathIcon icon1 = null;
object resource;
if (Application.Current.Resources.TryGetValue("PhoneIcon", out resource)) {
  icon1 = resource as PathIcon;
};

Alternatively, I can create it like this (avoiding querying resource dictionary):

var icon2 = XamlReader.Load(
  @"<PathIcon 
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
        Data=""F0 M22,22z M0,0z M17.4,22.533333C19.111111,25.955556,22.044444,28.766667,25.466667,30.6L28.155556,27.911111C28.522222,27.544444 29.011111,27.422222 29.377778,27.666667 30.722222,28.155556 32.188889,28.4 33.777778,28.4 34.511111,28.4 35,28.888889 35,29.622222L35,33.777778C35,34.511111 34.511111,35 33.777778,35 22.288889,35 13,25.711111 13,14.222222 13,13.488889 13.488889,13 14.222222,13L18.5,13C19.233333,13 19.722222,13.488889 19.722222,14.222222 19.722222,15.688889 19.966667,17.155556 20.455556,18.622222 20.577778,18.988889 20.455556,19.477778 20.211111,19.844444L17.4,22.533333 17.4,22.533333z"" 
        />"
) as PathIcon;

Both ways get me a PathIcon instance that looks just fine (icon1 and icon2 seem to be identical).

Debug.WriteLine( 
  "{0} equals {1}: {2}",
  icon1.Data.Bounds, icon2.Data.Bounds,
  icon1.Data.Bounds.Equals(icon2.Data.Bounds)
); // outputs 13,13,22,22 equals 13,13,22,22: True

I'm trying to use the icon for an AppBarButton:

        SomeCommandBar.PrimaryCommands.Add(new AppBarButton(){
          Label = "Label",
          Icon = icon1 or icon2,
          Command = SomeCommand
        });    

The problem is: when I use icon2 (created with XamlReader), everything works just fine, but when I use icon1 (fetched from resourcedictionary), I get a XamlParseException:

"Failed to assign to property '%0'. [Line: 0 Position: 0]"

I'd appreciate any ideas as to why this may be happening.

UPDATE

This doesn't work either (the error is the same as above):

<Page.BottomAppBar>
    <CommandBar>
        <AppBarButton
            Label="Test"
            Icon="{StaticResource PhoneIcon}"
            />
    </CommandBar>
</Page.BottomAppBar>

So, I guess, there's no way this can work at all. It simply doesn't work with static resource in this place. Guess I'll have to store string resources with icons and XmlReader.Load() them every time, as Chris W. suggested in the comments.

HOWEVER

The following does work for some reason (not that it's useful in any way):

  PathIcon icon1 = null;
  object resource;
  if (Application.Current.Resources.TryGetValue("PhoneIcon", out resource)) {
    icon1 = resource as PathIcon;
    // if the resource is removed from the dictionary before it is used,
    // no exception is thrown.
    foreach(var m in Application.Current.Resources.MergedDictionaries) {
      if (m.ContainsKey("PhoneIcon")) {
        m.Remove("PhoneIcon"); // This does it
      }
    }
  };
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Michael Antipin
  • 3,522
  • 17
  • 32
  • How are you fetching it? – Chris W. Jan 27 '16 at 14:42
  • It's the second code block of the question actually. – Michael Antipin Jan 27 '16 at 14:51
  • ah sorry, used to looking for the xaml equiv of {StaticResource ...} but you got the static application.current on there so I'm thinking I may be wrong anyway. – Chris W. Jan 27 '16 at 15:30
  • What puzzles me is the fact that I get the resource alright and can't notice any differences from the XamlReader-created instance. All of this is happening on the UI thread (the exception would by different otherwise). Wtf? – Michael Antipin Jan 27 '16 at 15:38
  • 1
    Something I sometimes do to re-use just the path data across multiple sources that might make a reasonable workaround is instead of pass the whole PathIcon as a resource, template the target to accept the path data string to the property and just plop your geometry in your dict like `F0 M22,22z M0,.......` – Chris W. Jan 27 '16 at 16:05
  • I've found a way this may work... The way is wrong, but at least this gives me an idea: you can't use a `FrameworkElement` resource while it resides in a `ResourceDictionary`, you have to remove the reference from the dictionary first. So, the whole idea of using resources this way was wrong. Ok, but using `{StaticResource PhoneIcon}` the declarative way still fails! This I can not explain yet. – Michael Antipin Jan 28 '16 at 16:35
  • Well that's not entirely true. I mean you could embed it in something made to contain CLR objects like a ContentControl and pass it around. Like if you just took your whole `` itself and threw it in one. Kind of like [this answer](http://stackoverflow.com/questions/13292179/best-way-to-use-a-vector-image-in-wpf/13293017#13293017) but using your FrameworkElement nested in there and passing it as content. You could do that. – Chris W. Jan 28 '16 at 16:49
  • Updated the post. I don't have more time for banging my forehead against this, so that's it for now. – Michael Antipin Jan 29 '16 at 09:15

1 Answers1

1

I find that the data path is far more complex in the declarative XAML of resources than the implicit converter of the Data property. Since you have it working as a Data property, let Visual Studio do the work. Open the properties dialog in the XAML designer and click the small right square (it will be black at first) net to the Data property and select "Make Resource". The resulting wizard will guide you, and you will see the data string is converted into its component parts and will work with way you want it to after you do this.

enter image description here

Best of luck.

Jerry Nixon
  • 31,313
  • 14
  • 117
  • 233