Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug Blend cannot find StaticResources that have been added programmatically
8 replies. Latest Post by shacktoms on September 9, 2009.
(0)
shacktoms
Member
185 points
149 Posts
09-02-2009 10:03 PM |
For example, create a class ColorGrid...
public class ColorGrid : Grid { public ColorGrid() { Resources.Add("Brush_Fill", new SolidColorBrush(Colors.Red)); } }
Reference it in XAML...
<local:ColorGrid Background="Blue" Width="100" Height="100"> <Ellipse Fill="{StaticResource Brush_Fill}"/> </local:ColorGrid>
Works in Visual Studio design mode, works in the running application, but fails in Blend 3 design mode. "The resource 'Brush_Fill' could not be resolved". The documentation is uniformly explicit that resources can be added programmatically.
odahan
Participant
1625 points
291 Posts
09-04-2009 1:46 PM |
Who were the first, the egg or the hen... that's the question :-)
Of course you can define resources by code and this will work, once the code will be compiled...
When you're designing under Blend, the latter can just see the xaml. Blend will not interprete your C# code, so it will not find the resource. You're referencing a "StaticResource", and you're defining a kind of "dynamic" resource by code. Something is wrong in this logic for Blend...
09-04-2009 2:58 PM |
Yeah, I could do that, except that my real situation is somewhat more involved. I just wanted to reduce the bug to a simple example.
The thing that is weird is that Blend obviously is running my C# code, because my outer control can do other things, like control layout or set properties that are seen by TemplateBinding. It seems that Blend must make multiple passes, and it resolves all of the StaticResource references before it actually begins to build the tree, at least that appears to be the effect of whatever it does.
I think it doesn't actually resolve the StaticResource references, but resolves to the definition of those resources and creates a separate instance for each reference. The upshot is that even if I create the resource in Xaml, it has no effect for me (in Blend's design mode) to modify its color in my C# code because the references are actually to different instances of the SolidColorBrush object. This is one of the reasons, I think, that Blend is so slow, especially if there are any resources whose instantiation takes a while. This works much better in the run-time engine, and in Visual Studio's design mode.
09-04-2009 10:49 PM |
Blend is a "young" product. Version 3 is really fantastic but there are still topics that can be improved, surely.
You said that Blend is running your C# code, of course, if you create a UserControl and once it has been compiled Blend can instanciate the control but not the parent UserControl you're working on, this one is being modified and the dll (if already compiled) is no more up to date. It will be updated on next build. So this is perhaps what you're descripting as a "two passes" system.
To solve definitively this problem Blend should have to interprete C#, and C# is not JavaScript, it must be compiled to work. I don't know how the Blend team will reduce the effect of this problem in future releases, it's certainly hard because it's a paradox :-)
The egg and the hen. An old problem :-)
09-06-2009 3:13 PM |
The parent UserControl is not the problem. The problem is that Blend cannot utilize the pre-compiled ColorGrid control as a child. There is nothing about the use of the ColorGrid control that requires it to be recompiled. The same bug would hold if ColorGrid were part of an external, pre-compiled dll.
Visual Studio's design mode does not have the problem, so I don't think there is any essential impediment to fixing the bug.
There is no egg and hen problem here, there is a strict order in the creation, compilation, and use of all the objects. There is no cycling of information from a later step back to an earlier step.
09-08-2009 11:05 AM |
You're speaking about VS design mode, but since Silverlight 3 there is no more VS design mode for Silverlight, so are you using an old version of the latter ? (SL 2 / Blend 2 ?)
09-08-2009 12:42 PM |
VS Design Mode is still there in SIlverlight 3, it is just not displayed by default.You just have to move your cursor to the bottom of the Xaml display, just beneath the horizontal scroll bar, and when the cursor changes from the usual pointer to a horizontal line with an up and down arrow (you may have to hunt for it, there seems to be only a 1 pixel high channel where it changes) you can drag the top of the design window up from the bottom to make it visible. This actually speeds up the design mode, because I tend to have lots of test pages for my individual controls and the default avoids running the ones I am not currently working on.
Don't get me wrong, it isn't perfect. But, unlike Blend, I have workarounds for most of its deficiencies, the main one being that Application-level resources aren't made available to StaticResource references within templated controls that are styled in generic.xaml within a referenced dll. It also requires some thread synchronization in order to get design-time animations to not break everything. But after working around these kinds of things, it tends to actually operate more like Silverlight.
Blend is more frustrating because it seems to be mostly about using Silverlight to implement a Blend application rather than about using Blend to design a Silverlght application. There are lots of capabilities that Silverlight has but which break Blend. This is really unfortunate because I would like for my designers to use Blend, but Blend's deficiencies limit my ability, as developer, to make things easy for them (e.g. by creating a system of Brushes which utilizes a known palette of named colors that has defaults and fallbacks, so that, for example, the IntraOp tab text color may be set on its own, but it defaults to the overall text color, whatever that is set to. That is possible in VS, but I don't want them to have to use VS).
I also want to impose, within the application, a discipline of using named colors so that I can support color changes, such as dynamically-loaded palettes (and SolidColorBrushes are very nice in that when you change their Color, everything that is painted with them immediately changes, even without using Binding or Animation, but that feature doesn't work in Blend because it doesn't actually resolve StaticReferences to the given resource, it creates a new resource for each reference).
09-08-2009 3:31 PM |
<<You just have to move your cursor to the bottom of the Xaml display, just beneath the horizontal scroll bar, and when the cursor changes <<from the usual pointer to a horizontal line with an up and down arrow
It's a very cool trick, thanks. As I'm using Blend for the visual part and VS only for code and debug I have not investigated too far and was thinking the design view was dropped out... I'm glad to get again the snapshot view of my Xaml :-)
I'm also trying to see how I can make my designer working on Blend, simply. But it's a bit harder I was thinking.. Blend is a very cool product, with some limits, but I found the main problem is not Blend but the way to well cut the job between developers and designers. Silverlight, like WPF is offering a lot of ways to achieve the same thing. I noticed that when I'm working like usual it often results in situation where things are not simple for my designer. And as she is trying to understand developer way of thinking her creativity is shot down... Developers think C#, not design. So they implement code and think like they're coding. Under Blend some good developer solutions can be hard to understand for the designer. It's why I'm forcing myself to work on Blend to find the right way to separate the job and to be able to explain this new way to both my developers and my designer...
For the color problem, I'm doing the same (defining resources). I'm using colors defined as Color resources and all is working fine in Blend. When I change the value of one color all elements using it are updated as expected. I'm using Color resources, not Brush resources, perhaps that's the difference between your way and mine ? What if you define Color resources instead of brushes can it be a solution to your problem ?
09-09-2009 2:59 PM |
When you say that all the elements using the color change, I think you mean that they will be different immediately in the design tool and that they will be different the next time you run the application. On the other hand, changing the Color of a SolidColorBrush will change the color of anything painted with it in the running application, in real time.
I don't think that can happen with a Color. In the first place, Color is a value type (a struct), so it cannot really be shared between all the objects that use it. It gets copied on reference in much the same way that Blend does (erroneously in my view) with all resources.
But maybe it gets me closer. Maybe I can define my named Brush resources to refer to named Color resources and my designer can then just have the commonly-colored Brushes refer to the same Color. At least, this way, the commonality is explicit where it is intended instead of appearing to be accidental (after all, some things do just happen to have the same color even though they are not related). Thanks for the help.