I'm having a couple of major issues when trying to style the ChildWindow control from the SDK.
First issue:
ChildWindow doesn't pick up implicit styles. I understand why, it's because the actual child window is always a derived class.
I know that I can just use an explicit style instead and that's my current solution, but is there any other way to work around this problem so that I don't have to remember to explicitly tag all child windows with the same common style?
Second issue:
We're using Prism 4 and I have a child window instance in a module that is loaded dynamically by the Prism infrastructure. It picks up the explicit child window style, but it doesn't pick up any other implicit styles defined in the shell's App.xaml (such as the TextBox control template).
This only appears to be a problem inside dynamic modules, it's fine with shell-based windows. Any ideas why this is happening and what I can do to fix it?
For your first issue, are you targeting ChildWindow to style a derived one? If so, you need to specified the derived type for the TargetType so that the implcicit style can kick in.
As for your second issue, I am not 100% sure how to fix this but what we found out is that if you declare your implicit styles inside the main window's resources, it will be applied to the controls that reside in your external modules. But I think that this was not working for explicit styles though...
Turns out that Prism wasn't the problem - there were implicit styles defined in the child windows that were wiping out the implicit styles from the shell because they weren't using BasedOn. After adding this attribute everything works fine now.
Related
EDIT: I was able to reproduce this in a very stripped-down version of the application. Here is a link to the .zip file
http://www.mediafire.com/?cn918gi15uph1xe
I have the module add the view to two different regions - the status bar region along the top is where the issue occurs. The weird part is, when the same view type is added to the main region, there are no problems. The status bar region is an ItemsControl and the main region is a ContentPresenter. That is the only difference.
Please let me know if you have any insight! Thanks.
-----Original Post-----
Hello all,
I am seeing some weird behavior with WPF. I'm using .NET 4 and PRISM v4. The way we have our application structured is that the skin resource dictionaries exist in their own assembly. The modules do not reference this assembly - instead we have a skin manager class that reads from a config file which skin we want and loads the appropriate components into a merged dictionary. The merged dictionary is set in the Application resources (we clear out the Application.Resources.MergedDictionaries before we add it). The idea is that we can later switch skins at runtime if needed, and the modules don't need to know about the skins until runtime.
Then in our xaml we are referencing styles using DynamicResource. The problem has to do with a TextBlock style defined in the skin and referenced by key, such as
<TextBlock Style="{DynamicResource someKey}" ... />
The style defines the font family, font size, and foreground. The font family and size are applied correctly (I verified this). The foreground, however, is always black. I used Snoop and WPF Inspector to see that the foreground value is "inherited" instead of coming from the style.
I also have a control that inherits from TextBlock and all it does is add some properties that determine what the text value should be (it doesn't affect the style at all). I was able to add a property changed override for the Foreground property and found out that the style's foreground value gets applied, and then the inherited value gets applied after that. I wasn't able to get the .NET source debugging to work so I couldn't figure out why/where it was being called from the second time...
Here is a link to an old, old post from a guy with the exact same problem - he did not find the answer, but instead a workaround. Unfortunately the workaround only works on the inherited control (I can't set InheritanceBehavior for TextBlocks).
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3501ed19-ab40-4064-81b5-e9b7b9d35b56
My guess is that for TextBlock the foreground property is inherited from its parent unless you explicitly set it on your TextBlock instane. For example if you change the Window or UserControl that this Textblock is in to have a Foreground of blue does it work? One thing you can try doing is in the style instead of setting just Foreground to a color, set TextElement.Foreground. See if that works.
It doesn't explain why the problem exists, but a fix was found here:
http://compositewpf.codeplex.com/discussions/257596
The fix is to load the skins before creating/adding views to the shell.
I am new to Silverlight, but I couldn't find anything about this when I googled it.
I have a button that I am trying to set the style programatically. I have the style defined in a XAML file and I want to pull the style into C# so I can dynamically create a button and assign it this style. So far, this is what I am trying:
button.Style = (Style)Resources["CloseButtonStyle"];
However, it just makes the button have no style. Is there an easy way to do this? I feel like this should be obvious, but I can't get it to work.
You are assuming that your Resources property on the current object is the one that contains the defined style. However, I assume, given the symptoms of your issue, that CloseButtonStyle is actually defined further up the control hierarchy.
Instead, you need to traverse your control hierarchy until you find the resource (or if you know the object that defines it, just refer directly to that object). Unfortunately, Silverlight doesn't include FindResource call like WPF, but it's not too difficult to implement your own.
I can call button1.Style = (Style)Resources["NonExistentKey"]; and it makes my button have no style at all as well, point being that the resource is probably not being found, you won't get an exception.
You directly access the Resources property, but is the style really in the immediate resource dictionary of your Window/UserControl/whatever-you-have?
I wanted to know which one amongst Style and UserControl would be better to use in WPF?
For example:
I have created an image button in two different ways.
One uses Style and ContentTemplate property is set.
It uses one other class with dependency properties.
The other way is I have created a UserControl which has a button and its content property is set.
The file UserControl.xaml.cs also contains the dependency properties.
For Code details see the answers of this question:
Custom button template in WPF
Which one would be better to use? In which scenario should one go for Style or UserControl or any CustomControl?
Styles are limited to setting default properties on XAML elements. For example, when I set the BorderBrush , I can specify the brush but not the width of the border. For complete freedom of a control’s appearance, use templates. To do this, create a style and specify the Template property.
Styles and templates still only allow you to change the appearance of a control. To add behavior and other features, you’ll need to create a custom control.
For example,
To create a button like a play button use styles and templates, but to create a a play button which will change its appearance after pausing it use UserControl.
For this type of thing I would go with Style, even though I'm not really adept with graphical tools. I tend to produce a basic, boring style that I can get started with and then prettify it once the application functionality has been verified.
The nicest thing about WPF is being able to distance much of the graphical look, feel and behaviour away from the code.
This allows you to change the style of your application without revisiting the code and indeed means that you can change styles on the fly at runtime.
There is an awkward line to tread with regards to how much behaviour is placed within the XAML and how much is placed within the code. A rough guide would be to decide on what behaviour must always be present within the UI and place that in the code, everything else place within the XAML.
Think of the code as being an abstract class with defined interfaces and the XAML Styles as being classes based on that class and you'll get an idea of what I mean.
Conversely, I know that people who are far more adept at the GUI work prefer to put more functionality in the XAML and others who prefer the code side, because they find the GUI work slow or difficult.
When thought of that way you'll see that there's never really a right or wrong answer, just better solutions that suit your skills.
if a style is used, it can not be modified agaign. so i need a clone method. but its hard to implement.
what i want to do is implementing a cascading 'style' mechanism. for example, i set two style to the same frameworkelement. the same property of latter style will override the former one, while the different property remain unchanged.
but if i set the style property of the frameworkelement twice directly, the 1st style will be gone. so i use the baseon property of style class to do that. but now come across another problem, the style can not be modified after it's been set to a frameworkelement.
so now i need a clone method.
Kevin,
I have written a CloneObject class which is exactly what you are looking for. Check out my code here:
"Generic class for deep clone of Silverlight and C# objects".
Jim
thanks jim. i finally discards this 'clone' idea, because it's not that easy and seems to produce some buggy problem. so i try to create a xaml resource file, and every time i need to create a instance, i just load the xaml and call the XamlReader.load.
this can bring some performance issue, but i think the cost is acceptable. and i can do styling job in blend for that specified xaml file.
I try to use inheriting in WPF. I have asked a question about this earlier, but no one answered correct. So I try to make a BaseWindow class with some UI elements and I want that other windows, that inherit my BaseWindow would have these UI elements. How to do that. My practise with WinForms applications dont work anymore. Maybe there are some simple examples or smth..? Thanks
If you want to inherit from a window, you need to create an implementation of a window in code only, and you can then inherit from this - note that your Window declaration in the XAML would need to change to point to this code, e.g.
<src:BaseWindow xmlns:src="clr-namespace:BaseWindowNamespace" ...>
If you define the base window using XAML, you'll get the following errors:
"'WpfApplication1.Window1.InitializeComponent()'
hides inherited member
BaseWindowNamespace.BaseWindow.InitializeComponent()'.
Use the new keyword if hiding was
intended"
"BaseWindowNamespace.BaseWindow cannot
be the root of a XAML file because it
was defined using XAML"
Now, at this point, I must point out that this is counter to the way that you should handle composition of your window. The "standard" way of doing this would be to use content templates to display user controls which could be swapped and styled to achieve different looks and functionality. In this way, the function of the window becomes that of a harness, and you can achieve a clean separation of content which can be easily implemented using MVVM.
Did you try the BasedOn tag? I don't know about windows, but that's what you use for UserControls AFAIK.