How to put a complete dark theme into my UWP? - c#

I'm trying to made an UWP app that can change of theme. I'm using the instruction RequestedTheme = ElementTheme.Dark;, but this only changes the "basic items", I'm talking about the background and text.
The textBox, the ContentDialog and others aren't into the dark mode.
I'd like to find a way to "dark" ALL the items into the app, not only the text and background.
Hope there's any way.

You can set theme on the application and element level.
If you want to set it on application level, it must be done when the app is started (in App.xaml.cs constructor). This setting cannot be changed at runtime.
To switch theme at runtime, you can utilize the RequestedTheme property on a control. This applies the theme to the control and its children in the visual hierarchy. This can be switched any time at runtime. To make the selected theme apply to the whole application, you need to set it on a top-level visual element - ideally the root element of the window:
var root = (FrameworkElement)Window.Current.Content;
root.RequestedTheme = ElementTheme.Dark;
Usually, the window's content is a Frame but, more generally it can be an arbitrary FrameworkElement.

Related

MahApps Metro DialogCoordinator: Display Dialog to span UserControl only (instead of entire window)?

I'm epxloring different ways to best show dialog windows in my application.
MahApp Metro's IDialogCoordinator seems quite useful, but I couldn't quite adjust it to my use case yet.
Say I'm creating a UserControl (view), whose ViewModel needs to be able to display dialogues.
These dialogues should, when displayed, overlay/span the UserControl only, NOT the entire Window in which the UserControl is hosted.
Is there any way to achieve this?
Default behavior always seems to span over the entire window, and I haven't found any way to change this yet.
So far, I've been using the Dialog coordinator in a very straightforward way, doing the following in my view:
<UserControl
xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
Dialog:DialogParticipation.Register="{Binding}">
and set set the instance in my view's constructor by,
viewModel.Initialize(DialogCoordinator.Instance);
which I'd then call in the viewmodel via
IDialogCoordinator _DialogCoordinator; // set with viewModel.Initialize() called from the view
private async Task _SomeCmdExecute()
{
await _DialogCoordinator.ShowMessageAsync(this, "HEADER", "TEST");
}
Thanks!
Dialogs in MahApps.Metro are always at the window level (see the container PART_MetroActiveDialogContainer in the window's style.)
What you can do is changing the styling of dialogs, so they don't stretch horizontally accross the entire window. See the default template MetroDialogTemplate for reference.

How to access PickerFlyout's app bar in a WP 8.1 XAML App

I'm writing a custom picker with the PickerFlyout class. By setting the ConfirmationButtonsVisible property to true, the flyout will show an application bar with an accept and a cancel button.
My problem is that the picker I am writing does not always have a valid value, and therefore I would like to disable the accept button when it does not make sense. Is there a way to do this in a Windows Phone 8.1 XAML app ("Store app")?
Other possible solutions:
An alternative solution would be to show my own app bar instead of the one given by ConfirmationButtonsVisible, which is possible by setting one in the Opening event. However, when this is done if the "overflow dots" of the application bar is clicked, the flyout will close. Apparently there is no way to prevent a flyout from closing.
If all else fails I will have to write a custom Popup, but I would rather not do this because the opening and closing animations used by PickerFlyout do not seem to be available as resources (internal to the class maybe?).
As long as there are items only in the PrimaryCommands section the flyout stays on screen when the overflow dots are tapped. Thus it is possible to temporarily replace the page's app bar with a new one for the duration of the flyout as long as no items in SecondaryCommands are needed. The accept button can be disabled in this new app bar.

WPF Navigation and Rotating Backgrounds

I'm working on an application, and I'm using the MVVM approach.
Basically, there are currently two Pages, and 1 MainWindow.
I switch between the pages using a Frame inside MainWindow.
In the main window, there are 2 buttons which are basically global and should show in all pages; x (exit) and settings.
This is basically my 'shell', as I decided to not use a window border.
The problem is I'd like each page to have a different background and this is where it gets complicated:
- Settings page: Grey background.
- Main Page: Rotating background color that changes according to a property.
The thing is the background is being set in the main window, because it should apply to the global area as well (the top, where the exit and settings buttons are).
I first set the background (in MainWindow) as bound to a property the represents the current page (the value is then being translated into a color hex code with the help of a converter).
All in all, this results in a case where the background changes when a page is changed, but not when the property inside MainPage changes. I can clearly understand why, but I have no idea how to solve it.
The possible solutions I came up with so far:
Somehow causing the binding in MainWindow to update/refresh when the property is changed in MainPage.
Changing the background manually from inside each of the pages. (Although doesn't it negate the idea of mvvm?)
Move the background into each of the pages and set it from there, while making the global buttons on top of the page (which could be a bad thing in case controls end up overlapping).
If so, what would be the best solution to this problem?
If you haven't already, I'd suggest you install some package via NuGet to make MVVM style development more enjoyable. I personally prefer MVVMLight which is... well, light, but it also packs lot's of helpful features.
To communicate between ViewModels, you have (at least) two possible approaches.
1) ViewModelLocator (not recommended)
ViewModelLocator is central place holding references to all of your viewmodels. You could add a property that is then used by all of the viewmodels to get/set the background.
....
x:Name="Main"
DataContext="{Binding Source={StaticResource Locator}, Path=MainVM}">
....
<Grid Background="{Binding Background, Converter={StaticResource StringBrushConverter}}">
...
2) Messenger (recommended)
When ever property changes in your viewmodel(s) or method is executed, you could send a message that your MainViewModel is registered to listen to. Sending a message would be as easy as...
Messenger.Default.Send(new UpdateBackgroundMessage(new SolidColorBrush(Colors.Blue)));
And you'd register for this message in your MainViewModel's constructor:
Messenger.Default.Register<UpdateBackgroundMessage>(this, message =>
{
Background = message.Brush;
});
Actual message class would be:
public class UpdateBackgroundMessage : MessageBase
{
public UpdateBackgroundMessage(Brush brush)
{
Brush = brush;
}
public Brush Brush { get; set; }
}
I know I'm simplifying things here but I hope you got the idea. Both approaches are valid even if you decide not to use MVVMLight.
Edit:
Here's Git repo with example https://github.com/mikkoviitala/cross-viewmodel-communication
I think you should use Application Properties for storing background. There are various benefit of this :
1) Globally available
2) Easy to remember or store user preference
3) Automatically maintain separate profile for each user as it store values in AppData folder of user.
you can use Messenger to notify that background property has changed so that main window or shell could pull out new background value and update it.

Creating popup without possibility to tab to a background element

I am trying to create a popup but when it is open it is still possible to use the tab key to switch the focus to an element in the background (e.g. to a button and use space to press is). The only way I found until now is to check on every lostFocus event (which also fires for every element contained in the Border element) and check if the focus is now in a element inside the Border. If not I manually set the focus.
Is there a nicer way to keep the focus within the Border (or a Grid,...)
I'm working on a Windows 8 App.
Do you mean that using a Modal Dialog with Form.ShowDialog(Owner) still allows you to focus the parent components with Tab?
Can you give a sample of your code call?
Form2 form = new Form2(); //Make an instantiation of your Form
form.ShowDialog(); //ShowDialog()!!! NOT form.Show()!!! Or anything else :/
A few ideas:
Set Enabled to False on the background visual tree, though that might change the way things look if you still want to show them partly
Set IsHitTestVisible to False to disable pointer input
Use RenderTargetBitmap.Render() if targeting Windows 8.1 to render the content of the background to an image and simply replace all that visual tree with an image of it

How to have no/one window title and have a different title for the task bar?

Windows Explorer in Windows 7, and maybe Vista too (can't rememmber), does not have a title in the window. but does have a title (some text) in the taskbar.
Is this possible to reproduce in C# (wpf or winforms)? either through the framework or introp.
I want to have a window that says "Options" in the taskbar but the window itself doesn't have a title.
MSDN has a nice article called Custom Window Frame Using DWM which discusses the things you can do with the window frame using the DWM of Vista and Windows 7. In particular, the Removing the Standard Frame section should be relevant for your case.
look at http://blogs.msdn.com/wpfsdk/archive/2008/09/08/custom-window-chrome-in-wpf.aspx for the section titled "Vista Explorer – Removing redundant information from the title bar"
Simply add the following attribute to the Windows element in your .xaml file
WindowStyle="None"
Side notes:
Task Manager can have a title bar or not have a title bar, depending on what mode you have it in; double click on the margin to toggle the mode. Also note, the quickest note to bring up Task Manager is Ctrl+Shift+Esc. Also check out the BorderThickness and WindowsState attributes of the Window element.
Credit to the Particle Effects Example in WPF MSDN docs.
Have you noticed a Property of the WPF Window:
ShowInTaskbar:
Gets or sets a value that indicates whether the window has a task bar button. This is a dependency property.
I think this may be helpful. You can set WindowStyle Property to "None" with the ShowInTaskbar Property set to "True".

Categories