I am using both XamTextEditor and XamMaskedEditor in a container control (Xceed DataCell) that changes its background colour depending on whether it is in edit mode or not. To not obscure this background effect, I have set the Background of the XamTextEditor and XamMaskedEditor controls to Transparent.
However, it seems that XamTextEditor automatically adjusts its Foreground according to the containing control's background colour, but XamMaskedEditor does not. This is particularly prominent in when using 'Windows XP' theme/style with the colour scheme set to 'Default (blue)'.
I tried putting the XamTextEditor and XamMaskedEditor controls on another control (a StackPanel) with its Background set to DarkBlue, but neither of the controls' Foreground changed to white; both remained black. So, it appears that the DataGrid is "telling" the editor control to change its Foreground, but it is not doing so on the XamMaskedEditor for some reason. Is this a failure on the part of the DataGrid or does the XamMaskedEditor not conform to some requirement?
I've attached an example project demonstrating this. Simply set your Display Settings to use 'Windows XP' theme, colour scheme 'Default (blue)' and then run the application. Click 'New Item' and type into both cells. The first one (which uses XamTextEditor) automatically provides a clear white Foreground against the dark blue background. The second one (which uses XamMaskedEditor) shows the standard black Foreground which is difficult to see against the dark blue background.
Unfortunately, I could not include the third-party DLLs in the attachment due to size limitation, so, as you have done previously, you will need to download and install Xceed DataGrid for WPF 3.7 control suite from here (site registration may be required).
This appears to be a bug with the XamMaskedEditor. Is there a workaround? Can this be submitted as a fix request?
Thanks,
Jason
Xceed have investigated this and it appears it may be an inconsistency between the XamTextEditor and other types of control. It seems that XamTextEditor changes its Foreground colour according to the containing control's Foreground colour. However, other controls (including XamMaskedEditor) do not do this.
http://xceed.com/CS/forums/permalink/26894/26894/ShowThread.aspx#26894
Is there a resolution?
I want to make sure I understand you before I report an issue. The title of the original post was a bit confusing since controls do not change their Foreground based on their Background. Foreground is an inherited DependencyProperty that if not set on an element is inherited from an ancestor on which it was set. In looking at the xamMaskedEditor and xamTextEditor with regards to foreground, it would seem that there are 2 issues.
First, the xamMaskedEditor's background defaults to the system Window color but the foreground is hard coded to black. The foreground should be bound to the WindowText color.
Second, while the xamTextEditor's Background defaults to the system Window color, the foreground is not set and therefore since Foreground is an inherited dependency property it will inherit the foreground of the ancestor element. Since the Background defaults to WindowBrushKey, the Foreground should default to WindowTextBrushKey. This would be consistent with what the TextBox does.
OK, well the xamTextEditor works well for me doing what it currently does, but this is obviously a fluke because it shouldn't be behaving that way.
I guess the proper way to do this is to base the Foreground of a transparent control (in this case, both xamTextEditor and xamMaskedEditor) on the Background of the containing ancestor.
For my particular case, I used Mole to find out which ancestor was providing the dark background colour and it is Border. I have put a Binding on the Foreground using a converter class to convert the colour. This appears to resolve it. I've attached the solution.
Thanks for your help. I guess there's still a couple of bugs to resolve on your side, though.
Cheers,
Well the template change may be subtle. Maybe they need to put another element in the template (e.g. a panel to contain the current element and another and instead of setting the background on the border they set it on the panel) or maybe during a bug fix they determine that that layer isn't needed and they remove it. These are unlikely but the possibility exists. To most developers changing the internals of an element's default template would not likely be thought of as a breaking change. Maybe that's why FindAncestor isn't even supported in SL.
With regards to a better solution I can't say I've considered it before now but off the top of my head I cannot think of anything better. At least in your case you know the specifics of the situation in which this is occurring so you don't need to worry about lots of those downsides that I mentioned if a control vendor were to try and incorporate such functionality into a control itself. Having the element inherit the foreground and ensuring that when you set the background you set a foreground that takes that into account is another way but then you have to make sure that elements do not set the foreground (explicitly or implicitly in their default styles, etc.) or else the inherited value won't be picked up. If the foreground is set in the default style (as it is in the xamMaskedEditor and TextBox and will be in the xamTextEditor when that bug is addressed) then that would likely mean having to provide a local style for those elements that sets all the property values and setting the OverridesDefaultStyle to true would be needed.
OK, thanks Andrew, and I take your point. But I would hope that the vendor does not change the way their template is set up for this particular feature on the basis that it could break controls used in its CellEditorTemplate that depend on the template's structure. I'm not sure if it's right for me to assume this, or for them to take this into consideration. Maybe it's subjective.
That said, can you think of a better solution to adjust a transparent control's Foreground based on the actual colour of the area immediately behind it?
I think the two issues that I pointed out are bugs and I will submit them. If you are binding the Foreground of the element then these shouldn't affect you as your local value will take precedence.
I'm glad you were able to workaround it for your scenario but I would be careful as that could change should you change the theme or if the other vendor changes the way their template is set up.
From a control vendor perspective, I don't think a control could reliably and generically base/manipulate its own Foreground based on the Background of an ancestor. There are many ways that that can break down: