I'm working on an app where I want the color of a few borders to change depending on the users choice of theme. The borders are partly placed in the xaml, but also dynamically generated throughout the app depending on choices the user make. I am also using a few LoopingSelector controls (from the Silverlight toolkit), that in turn also generate borders.
So, I was wondering how I should approach this problem. Initially I tried applying a style to the borders, and then changing the style depending on the choice of theme, but apparently styles are read-only during run time. I also figured I could iterate through and change the color of the borders, but it seems the LoopingSelector doesn't expose that property of its borders, or really, expose the controls at all.
So I assume I should use binding in some way, but as I'm still quite new to Silverlight I'm not really sure how to go about that.
Thanks in advance.
If you have a named resource, say CustomBorderBrush, that you are using in your XAML for the parts that are in the XAML, then you can access this brush from the Application's resources:
Border newBorder = new Border();
newBorder.BorderBrush = (Brush)Application.Current.Resources["CustomBorderBrush"];
If you additionally have a problem with the LoopingSelector, then that's a separate issue :) It sounds like you need to apply your own style to the LoopingSelector so that you can specify the brush value that you need.
Related
I am working on new WPF/MVVM project, where I see all most all controls are written for different needs, right from textbox to treeview. All are rewritten for simple need, for example, grid,stackpanel control are rewritten to add space between each item and textbox is rewritten to include label for it so that it has both label and text input are on itself.
My question : Is there any serious issue we would encounter because of this customization?
Already, I am seeing issues with aligning all controls, will i would see any more issues because of this?.
You should never create a custom or user control to add margins, a label to a TextBox, or a new ItemTemplate to a ListBox.
UserControls are for grouping frequently used combinations of controls into one reuseable control. An example may be a custom List-of-Values control that opens a dialog. This would be fine to implement as a UserControl.
Custom controls are good when a native control does not suit your needs. Say that you want to reimplement a DateTimePicker from scratch because the native one doesn't include milliseconds.
There are no serious issues as such, but you may find yourself maintaining all these controls for the next many years without there being a need to do so.
Settings Margins should be done in the View where you are using it, or on a Style in a ResourceDictionary.
This is of course only my opinion (and that of many others, I except), but if you find that the majority of your controls are 'customized' this way, you are doing it wrong.
Style and Templates rather than UserControls and custom controls.
The main issue is that you lose the ability to alter margins only in a single view. If you change your custom controls' inner paddings and margins, you will be changing all the views in your solution. If you use a style, you can always override it by defining a new style in the view, or by setting the property directly.
Lets say that, regardless of what color settings the user has, I want my app to have a white background with blue foreground elements, like the Skype app does.
How do I go about that? I've found how I can make elements use the system brushes, but I can't figure out how to change those default brushes. I also can't find where the background color is specified at all.
You can use a library created by Jeff called PhoneThemeManager. You can find the article about the same here: PhoneThemeManager. Just download it from NuGet and modify your app.xaml.cs file to get Light (white background) theme activated. The code is simple:
ThemeManager.ToLightTheme();
Once you apply the theme, all your pages will have white background. For blue foreground elements, you'll need to create your own styles and apply them to elements. I'll prefer Blend to create design template over here as you'll get WYSIWYG interface. Using system brushes will not help as those will change according to Accent color. Creating your own styles will give you more freedom and control.
I hope this helps.
Check out how to apply theme resources to wp8 app, it describes exactly what you're looking for.
The most convenient way to accomplish this Task is to use Expression Blend.
Expression Blend is most suitable for this purpose as it will provide and intuitive interface.
The Interface is shown below for a WP app (7.1, it applies to WP8 as well)
The interface is easy to use.
Select an Item on Objects and Timeline
An object is selected and UI updates in middle.
Now Check the right side for properties. See the Background is selected. Select the required color of choice and other properties.
Pros: This applies to various elements including Menu Items, Buttons and all.
Cons: Items such as MessageBox can't be customized this way.
So much reading, and so much about inheritance, I can't find any direct answers, so here goes.
If you have a base-class derived to do certain things, look or act a certain way, you can subclass it and get all the functionality of the parent class with only slightly modified differential. The same does not appear to be the same for working with WPF Themes... more specifically, the combobox control (similar issues with textbox, but that's obviously less complex).
By looking at the Control Template Examples, they discuss the entire structure of it, the borders, backgrounds, glyphs, actions, properties, etc.
If the ONLY thing I want to do with a combobox is to change the border of it to Red if there is an error in it, it appears, I have to basically redefine the entire thing and somehow put in my custom trigger setting / color to be implemented.
Somewhat similar is that of the textbox control and how its created. It has the named control when trying to nuts around with the background color... you can't just say... background = some static brush value.
What shortcuts are out there to only allow overriding these small elements without having to re-create the entire template control. I can just imagine what would go on with grids, tabbed controls, and others that could get extremely messed up if you miss one simple thing.
I also see that some controls are made up of OTHER Control.Templates, so how might I be able to attach to changing the property setting on just the single element of the control template... Such as the combobox has the control template for the Toggle Button. From that, it has a border via x:Name="Border" and I want to change THAT element within a derived style.
Thanks
I might not understand your question here. But from what i get is:
Yes you can't partially implement Templates, in fact i wouldn't know how this could be possible. But, if you want to change certain things, you can of course do that. You can create Styles, Templates, Brushes etc. as DependencyProperties and use TemplateBinding to bind to them, on the given child control.
Remember that WPF allows always to change the template on the fly. if we could partially change the template this would might hurt performance or could get messy and complicated. Still, you can do that using ContentControls and TemplateBinding or simply Triggers.
For my custom controls, which might contain multiple part sub controls, i usually add a style for them. For example, a custom ComboBox would contain a ToggleButtonStyle.
One thing that would be nice though, would be to add control template triggers without the need to reimplement the template.
I was wondering the need for custom xaml code for buttons.
Using images like in html should be faster.
Yours thoughts please.
The whole point of WPF is that it is independent of pixel resolution or DPI. If you use raster images for the buttons it is no longer DPI independent and can look bad on some resolutions. If, instead, you use WPF objects and geometries, those will look almost exactly the same on any DPI.
What happens when you want to change something small to do with the button? Using custom XAML allows me to apply the same template to all my buttons, and change them all by just changing that template. It also means that I can tweak small things without the need to constantly regenerate those images.
As for speed, you're best off not pre-empting the framework's optimisations until you actually encounter a performance issue.
EDIT: I should also note that the Image class doesn't inherit from Button, and as such you can't do the direct binding to an ICommand property in the ViewModel.
So I'm just starting out with WPF, and I'm really annoyed by the fact that if I lay two Grids on top of one another, the top Grid isn't opaque. It makes designing extremely annoying. Can this be turned off somehow?
I'm just building your standard Winforms STYLE application, but in WPF. I'm just trying to start bridging the gap here. In Winforms(and VB) you'd always have group boxes or something on your form, and then depending on some user context, one of those group boxes would be on top. Its how I've designed forms since time immemorial. One of two things must be true here:
A) This is not the recommended way to design Windows going forward with WPF, but I don't understand what you're supposed to do
B) There is some property to make the Grids opaque so I can build the Window in the style that I'm used to.
I'm fine with answers that solve either A or B. If I'm not doing things the right way because they've changed, then please enlighten me.
Update: So it turns out, I can make the grid opque by setting the background color, but now it seems like I'm locked into a White background as opposed to sticking with the system colors.
You could use SystemColors to make the control background colour match (rather than being white).
I don't understand why you want to put one grid on top of another though. In WPF you generally use a single grid to stack multiple visual elements within one region. Can you explain why you want to hide things in the background with foreground elements?
It sounds a little like you're implementing a tab control -- switching between pages of controls depending on focus. Have you experimented with the new TabControl?
I'm moving from WinForms to WPF development wherever possible and have found that in doing so it's taken some readjustment. WPF has a completely different way of laying things out and now that I'm more comfortable with it, I think it's superior. I'm guessing you just need to ride the learning curve a little longer.
Hope that helps.
EDIT: In response to your comment, I imagine you can have a tab control without tabs, though I haven't tried it myself (might be worthy of another question on SO). Tab controls are headered controls, meaning that they have a header item and a content item. In this case, the header is the tab button, the content is the page item. You can specify a ControlTemplate that details how these items should be displayed relative to one another.
Interestingly, many other types of common GUI element are also headered controls:
Menu items - The menu item text/icon is the header, and the optional submenu is the content
Tree view - Each node is the header, and optional children are within the content
Group box - The header is, well, the header and the content is, well, the content :)
Note that in the case of menu items and tree views, the type may recursively nest within itself. This is quite elegant and can give some wildly different presentation options over the same logical model with only changes to the control template.
For more information read about HeaderedContentControl and HeaderedItemsControl
You could use the following:
<Grid Background="{DynamicResource {x:Static SystemColors.WindowBrush}}">
<!-- content -->
</Grid>
This will respond to changes in the system colors on the fly (the DynamicResource does this).