question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Images from App.xaml Resource Dictionary not producing in Content Controls.

See original GitHub issue
  • .NET Core Version: .Net 5.0
  • Windows version: 10
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Unsure, it occurred on .Net 5.0 and the app is a bit too complicated to easily reproduce in an entirely new .NET Framework app at this point.
  • Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc…)? I doubt it. The bug occurs during a debug session. But hard to pinpoint the exact source here.

Problem description:

Quite unusual really. I have a set of definitions for icons in my App.xaml resource dictionary:

<Application.Resources>
    <ResourceDictionary>
        <BitmapImage x:Key="Position"  UriSource="Icons/Properties/Position.png"/>
        <BitmapImage x:Key="XPosition" UriSource="Icons/Properties/Position-x.png"/>
        <BitmapImage x:Key="YPosition" UriSource="Icons/Properties/Position-y.png"/>
    </ResourceDictionary>
</Application.Resources>

The position image isn’t necessary here, but I’ll mention it later. It’s mainly the X and Y position icons that are relevant for now. All 3 images are marked with Build Action “Resource” and told to “Copy if newer”. I’ve tried changing the Build Action to “Content” and “Embedded Resource” and the issue persists.

Now, in my MainWindow, I have a bit of a long-winded approach to accessing these images, but the key thing to note is that the X and Y Positions should be behaving identically. But the code for MainWindow looks like this:

public MainWindow()
{
    InitializeComponent();

    // Have changed this to XPosition and Position as well
    var prop = AnimatableProperties.YPosition;
    //MessageBox.Show(Directory.GetCurrentDirectory());
    var bmp = prop.Icon.Clone();
    Stack1.Children.Add(new ContentControl { Content = new Image { Source = bmp, Width = 36 }, Width = 400 });
}

Here Stack1 was just a Stack Panel. But the issue persisted whether I added the children to a Canvas as well.

The Animatable Properties class is just a class for easier accessibility of these things. It looks like the following:

public static class AnimatableProperties
{
    internal static AnimatableProperty<double, DoublePropertyControl> XPosition => new("XPosition");
    internal static AnimatableProperty<double, DoublePropertyControl> YPosition => new("YPosition");

    internal static AnimatablePropertyBranch Position => new("Position", XPosition, YPosition);
}

The relevant constructor for AnimatableProperty is:

public sealed class AnimatableProperty<TValue, TControl> : IAnimatableProperty where TControl : UIElement, IAnimatableProperty<TValue>, new()
{
    ...
    public BitmapImage Icon { get => Control.Icon; internal set => Control.Icon = value; }
    ...
    internal AnimatableProperty(string iconResourceKey) => Icon = IAnimatablePropertyExt.FromResource(iconResourceKey);
    ...
}

In short, this is just a long-winded approach to acquire the images from the resource dictionaries.

The relevant constructor and properties for AnimatablePropertyBranch are:

public sealed class AnimatablePropertyBranch : IAnimatableProperty
    {
        public BitmapImage Icon { get; set; }
        ...
        private readonly ReadOnlyCollection<IAnimatableProperty> _values;
        public ReadOnlyCollection<IAnimatableProperty> Values
        { get => _values; set { for (int i = 0; i < _values.Count; i++) { _values[i].Value = value[i].Value; } } }
        ...
        internal AnimatablePropertyBranch(string iconResourceKey, params IAnimatableProperty[] properties)
            => (Icon, _values) = (IAnimatablePropertyExt.FromResource(iconResourceKey), new(properties));
        ...
    }

Again, back to the MainWindow constructor, all that happened was that I added a basic content control containing the icon:

    // Have changed this to XPosition and Position as well
    var prop = AnimatableProperties.YPosition;
    //MessageBox.Show(Directory.GetCurrentDirectory());
    var bmp = prop.Icon.Clone();
    Stack1.Children.Add(new ContentControl { Content = new Image { Source = bmp, Width = 36 }, Width = 400 });

Actual behavior: The issue is a bit complex, and there may be multiple underlying issues.

Note that Position, XPosition, YPosition are all referencing the static properties of the AnimatableProperties class.

But the following things happened:

  • If the prop variable in the MainWindow constructor is either Position or YPosition, the debug raises an IO Exception saying it cannot find the file. (Again, recall that the files are set to copy if newer, and Build Actions “Content”, “Resource”, and “Embedded Resource” have all been tested to try to fix this.)
  • If the prop variable is XPosition however, the system is able to produce an image.
  • If I don’t clone the images from the resource dictionary, the Content Control simply writes out the BitmapImage.Source property as a string, and doesn’t produce any image.
  • No images are copied into the Icons/Properties folder of the Debug folder for the project. Not even the XPosition folder, which displays fine.
  • I have triple-checked the directories and everything, the files, file names are accurate. The image below contains a search result for files containing “Position” in the Project Directory. You’re free to double-check the spellings yourself. I added modification dates and times to show that they should all behave similarly, but don’t.

Screenshot (28)

  • If the Canvas or Stack Panel directly contains an image (ie. not through a Content Control, and therefore a Button as well, but an Image directly), then the images display perfectly fine for all 3 of XPosition, YPosition, and Position.
  • Cleaning and rebuilding did not fix the issue. Neither did closing and reopening Visual Studio.

Note that XPosition and YPosition behave differently, despite having the exact same underlying code to produce the images.

Only IO Exceptions were called, and they mentioned that they were unable to find the files for the Position and YPosition properties specifically. It’s worth clarifying, that there was definitely no misspelling of the resource keys, as it identified the appropriated directories to search for.

Expected behavior:

The images should have been copied to the Icons/Properties folder of the debug directory, and been visible regardless whether or not they’re inserted into the Stack Panel or Canvas via a Content Control or not. At the very least, XPosition and YPosition should have behaved identically.

Minimal repro:

The issue is a little complicated that I’m not sure a minimal amount of code will even reproduce the original issue.

But the steps to produce it would be:

  1. Create a WPF project.
  2. Add an image to some folder.
  3. Add image as a resource in a resource dictionary in App.xaml.
  4. Add the image to a Panel in the MainWindow from the resources via a Content Control dynamically (ie. not in the XAML code).

If you’re interested in a minimal repro, it would take some time to produce something similar, but writing this down took long enough. So I’ll try to do it soon. A little busy in the upcoming days though, so unsure how soon that will be.

The project is on GitHub privately, should anyone wish to pull it to their computer, I can add them to the repo temporarily.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
singhashish-wpfcommented, Nov 9, 2021

Thanks @osamakawish Closing this for now.

0reactions
osamakawishcommented, Nov 8, 2021

In fact, unloading and reloading the project seems to have fixed the issue. But please fix this issue so that others don’t run into it. VS doesn’t seem to always carry the action for CopyToOutputDirectory over to the csproj file, and that could confuse devs who are new to WPF.

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# Images in resource dictionary not appearing at runtime
I've separated all my images into a Resource Dictionary and assigned them in the XAML as static resources and this works fine at...
Read more >
Styles declared in Resource Dictionary not getting applied
When i run the WPF application then the Styles in the resource dictionary are not getting applied to the controls present in the...
Read more >
DesignTimeResources does not work
I have no solution for implementing the "App.xaml" type SHARED design time resources in a wpf control class library.
Read more >
Styles defined in Resource Dictionary are not accessable ...
I try to access these styles using <ResourceDictionary Source="Styles.xaml" />. But the problem is , these styles are not visible.
Read more >
Migrating the home page XAML and styles
Right-click the new Resources folder, select Add > New Item, select Resource Dictionary and name it Styles.xaml. To ensure the resource dictionary is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found