Maybe someone could show me how to correctly implement Async message into Metro window that it would have application's current theme and accent?
The code taken from the demo sample works, but theme and accent remain default:
private async void ClosingApp(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = !_shutdown;
if (_shutdown) return;
var mySettings = new MetroDialogSettings()
{
AffirmativeButtonText = "Quit",
NegativeButtonText = "Cancel",
AnimateShow = true,
AnimateHide = false
};
var result = await this.ShowMessageAsync("Quit application?",
"Sure you want to quit application?",
MessageDialogStyle.AffirmativeAndNegative, mySettings);
_shutdown = result == MessageDialogResult.Affirmative;
if (_shutdown)
Application.Current.Shutdown();
}
When I simply change the theme:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
// set the Red accent and dark theme only to the current window
var theme = ThemeManager.GetAppTheme("BaseDark");
var accent = ThemeManager.GetAccent("Red");
ThemeManager.ChangeAppStyle(Application.Current, accent, theme);
}
I get the default white and blue MessageBox. What am I doing wrong?
I've tried your code and it is working. I've only transformed the MenuItem_Click in a Button_Click but it is irrelevant.
I'm getting the black background and a red Quit like below, iff I close the App after clicking the settings button.
instead of the initial
I have the standard Window1.xaml starting with
<Controls:MetroWindow x:Class="TestFrontend.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
Closing="App_Closing"
Title="Test" Height="600" Width="600"
>
and the Resources in the App.xaml
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<!-- Accent and AppTheme setting -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I just needed to add the default Resource Dictionaries
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
in the App.xaml
Related
I want to display a MetroDialog with a custom background color, for error messages.
I tried using the property CustomResourceDictionary without luck:
Function to display message:
public static async Task<MessageDialogResult> DialogOK(string title, string message)
{
MetroDialogSettings settings = new MetroDialogSettings();
settings.CustomResourceDictionary = new ResourceDictionary { Source = new Uri("pack://application:,,,/MyApp;component/Resources/ErrorDialogRD.xaml") };
var result = await mainWindow.ShowMessageAsync(title, message, MessageDialogStyle.Affirmative, settings );
return result;
}
Resource dictionary:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro">
<Style TargetType="{x:Type Dialogs:BaseMetroDialog}">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
What am I missing? :)
How can i load style from below xaml using XamlReader.Load()
<Window
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
>
<ResourceDictionary>
<Style x:Key="LastRowHighlighted"
BasedOn="{StaticResource {dxgt:GridRowThemeKey ResourceKey=RowStyle}}"
TargetType="{x:Type dxg:GridRowContent}">
</Style>
</ResourceDictionary>
Try something like this:
public void LoadStyle(string fileName)
{
if (File.Exists(fileName))
{
try
{
using (FileStream fileStream = new FileStream(fileName, FileMode.Open,
FileAccess.Read, FileShare.Read))
{
ResourceDictionary resourceDictionary = (ResourceDictionary)XamlReader.
Load(fileStream);
Resources.MergedDictionaries.Clear(); // optional
Resources.MergedDictionaries.Add(resourceDictionary);
}
}
catch { }
}
}
Is there a way to create a ResourceDictionary Locator.
Right now I have in xaml:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../../Resources/StringResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Where the code behind sets the list of dictionaries based on currentculture
I'd like to have
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<Locator "StringResources"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Or something like that such that I don't have to modify each v.xaml.cs files
You could create your own ResourceDictionary:
public class ResourceDictionaryLocator : ResourceDictionary
{
public ResourceDictionaryLocator()
{
switch (CurrentLocalization)
{
case "English":
base.Source = new Uri("pack://application:,,,/Languages/English.xaml");
break;
case "French":
base.Source = new Uri("pack://application:,,,/Languages/French.xaml");
break;
}
}
}
Then consume it like this:
<Application x:Class="TestingWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestingWPF"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:ResourceDictionaryLocator />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
This is generally not done, however. You can load different resource dictionaries at runtime. Something like the following:
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(dictionary);
You can create a MarkupExtension that will return the requested ResourceDictionary:
public class ResourceDictionaryLocator : MarkupExtension
{
public string DictionaryName { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
// Logic to return the wanted ResourceDictionary
if (DictionaryName == "...")
{
}
return null;
}
}
Then use it in xaml:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<local:ResourceDictionaryLocator DictionaryName="StringResources" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
I really don't know if this is posible, but do you want to make that your application be 'Localizable'? Baybe this article could be helpful to you: http://www.codeproject.com/KB/WPF/WPF_Resx_Localization/.
I have a WPF application with a theme (ShinyRed.xaml) and I want to have a button that when clicked changes the theme to ShinyBlue.xaml
I load in the theme initially in App.xaml:
<Application.Resources>
<ResourceDictionary Source="/Themes/ShinyBlue.xaml"/>
</Application.Resources>
How might I do this?
How you could do it:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="ThemeDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/ShinyRed.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!-- ... -->
public partial class App : Application
{
public ResourceDictionary ThemeDictionary
{
// You could probably get it via its name with some query logic as well.
get { return Resources.MergedDictionaries[0]; }
}
public void ChangeTheme(Uri uri)
{
ThemeDictionary.MergedDictionaries.Clear();
ThemeDictionary.MergedDictionaries.Add(new ResourceDictionary() { Source = uri });
}
//...
}
In your change method:
var app = (App)Application.Current;
app.ChangeTheme(new Uri("New Uri here"));
Here is an article that will walk you through it:
http://svetoslavsavov.blogspot.com/2009/07/switching-wpf-interface-themes-at.html
Basically you need to remove the "old" theme from the resource dictionary and then merge in the new one. The above article shows you how to make this change very simple.
Im using the following command to set the theme at runtime:
Application.Current.Resources.Source = new Uri("/Themes/ShinyRed.xaml", UriKind.RelativeOrAbsolute);
App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Font.xaml" />
<ResourceDictionary Source="Themes/Light.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
In your code:
> Application.Current.Resources.MergedDictionaries[1].Source = new Uri("Themes/Dark.xaml", UriKind.RelativeOrAbsolute);
you can check with this to be sure nothing grow
Application.Current.Resources.MergedDictionaries.Count.ToString();
H.B.'s answer did not run for me, I had to do this (works, tested):
Uri dictUri = new Uri(#"/Resources/Themes/MyTheme.xaml", UriKind.Relative);
ResourceDictionary resourceDict = Application.LoadComponent(dictUri) as ResourceDictionary;
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(resourceDict);
To pretty it up:
// Place in App.xaml.cs
public void ChangeTheme(Uri uri)
{
ResourceDictionary resourceDict = Application.LoadComponent(uri) as ResourceDictionary;
Application.Current.Resources.MergedDictionaries.Clear();
Application.Current.Resources.MergedDictionaries.Add(resourceDict);
}
// Example Usage (anywhere in app)
private void ThemeRed_Click(object sender, RoutedEventArgs e)
{
var app = App.Current as App;
app.ChangeTheme(new Uri(#"/Resources/Themes/RedTheme.xaml", UriKind.Relative));
}
Hey Guys (and girls if any :)
I needed a different list box selection policy than the one provided by default with WPF listboxes, i.e. beeing able to have an extended selection withou any modifier key.
No problem on that, here is what I did :
class EnhancedCcyPairListBox : ListBox
{
protected override DependencyObject GetContainerForItemOverride()
{
return new CcyPairListBoxItem();
}
}
internal class CcyPairListBoxItem : ListBoxItem
{
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
IsSelected = !IsSelected;
e.Handled = true;
}
}
I can't tell if it's the best way to do, but it seems to work exactly as I expected.
Except that... by doing so, I have lost the defaults ListBoxItem style I had before. How can I tell to my derived classes to keep their default style ?
Thank you very much !
Add this above the EnhancedCcyPairListBox declaration
[StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof(CcyPairListBoxItem))]
Edit
Add this to the static constructor of CcyPairListBoxItem"
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CcyPairListBoxItem), new FrameworkPropertyMetadata(typeof(CcyPairListBoxItem)));
and in Themes/Generic.xaml add
<Style TargetType="{x:Type CcyPairListBoxItem}"
BasedOn="{StaticResource {x:Type ListBoxItem}}"/>
Because the WPF context of our application is quite special, I wanted to be sure that it was not an issue that was very specific.
So I took the above two classes and imported them in a brand new WPF test project. I created a Themes directory that registered a Resource dictionnary in which I put the Style as NVM mentionned earlier.
Content of Generic.xaml :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/InheritedListBoxStyling;component/Themes/Styles/TempDic.xaml" />
<!-- Reference here the Resource dictionnary used for your own component -->
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Content of TempDic.xaml :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:InheritedListBoxStyling="clr-namespace:InheritedListBoxStyling">
<Style TargetType="{x:Type InheritedListBoxStyling:CcyPairListBoxItem}"
BasedOn="{StaticResource {x:Type ListBoxItem}}"/>
</ResourceDictionary>
Content of Window1.xaml.cs
namespace InheritedListBoxStyling
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = this;
for (int i = 0; i < 50; i++)
{
source.Add("toto " + i);
}
l1.ItemsSource = source;
l2.ItemsSource = source;
}
public ObservableCollection<string> source = new ObservableCollection<string>();
}
}
Content of Window1.xaml :
<Window x:Class="InheritedListBoxStyling.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:InheritedListBoxStyling="clr-namespace:InheritedListBoxStyling"
Title="Window1" Height="300" Width="300">
<Grid>
<ListBox x:Name="l1" SelectionMode="Extended"
Margin="0,0,12,12" Height="100"
HorizontalAlignment="Right"
VerticalAlignment="Bottom" Width="120" />
<InheritedListBoxStyling:EnhancedCcyPairListBox
x:Name="l2" SelectionMode="Extended"
Height="100" Margin="12,12,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left" Width="120" />
</Grid>
</Window>
And here the result :
=> the default styling is not applied and, as in my "real case" issue, the only kind of styling that seems to be applied is the gray selected item style.
Any idea about what's going on or what I'm doing wrong ?