Anders
Anders

Reputation: 12560

Applying a global style/event to a MahApps.Metro textbox disables the watermark

I am developing a windows app and utilizing the MahApps.Metro from NuGet, version 1.5.0. I ran into an issue where setting global properties causes the textbox to disappear. Here are the steps to reproduce:

  1. Create new WPF application
  2. Install MahApps.Metro from NuGet (console or command line)
  3. Configure App.xaml and MainWindow.xaml (and .cs) to handle MahApps.Metro
  4. Create a simple textbox with the watermark property (Controls:TextBoxHelper.Watermark="<watermark here>" is default).
  5. Run application. Watermark shows up as intended.

Here is the .xaml for my sample app. Notice I changed Controls to mah (doesn't matter; I tried Controls and mah no difference was made):

<mah:MetroWindow x:Class="MahAppsTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        xmlns:local="clr-namespace:MahAppsTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBox mah:TextBoxHelper.Watermark="Test" Margin="5" VerticalAlignment="Top"/>
    </Grid>
</mah:MetroWindow>

Now if I go into the App.xaml file and add the following:

<Style TargetType="TextBox">
    <Setter Property="Margin" Value="5"/>
</Style>

Remove the property from the textbox (or keep it there, doesn't matter) then run the application, the watermark is now gone. It does not matter if it is a <Setter> or <EventSetter>. The watermark shows up in the IDE, though.

I saw on their GitHub repo under issues that some people had this solved by adding BasedOn="{StaticResource {x:Type TextBox}}" to the <Style> tag, but that all seems to be applied in the MainWindow.xaml or equivalent rather than globally in the App.xamlfile.

EDIT: I also tried adding the {x:Type ...} argument before making the post.

Has anyone experienced this and know a fix?

I am running MahApps.Metro v1.5.0 in Visual Studio 2017 programming in C# v4.6.1 (according to target framework) on Windows 10.

Upvotes: 0

Views: 1881

Answers (2)

Mike Strobel
Mike Strobel

Reputation: 25623

You need to base your style on the MahApps style. As written, you will extend the default TextBox style (which has no watermark). Try this:

<Style TargetType="TextBox"
       BasedOn="{StaticResource MetroTextBox}">
  <Setter Property="Margin" Value="5"/>
</Style>

I think that will work. You'll need to make sure the MahApps styles are in scope at the point where you declare that resource, though. If you're pulling the MahApps resources into your App.xaml, then just make sure this style is declared further down.

If for some reason this doesn't work, try replacing MetroTextBox with {x:Type TextBox}. It looks like MetroTextBox is the style name, but I could be wrong.

I'm not sure what you mean by this, though:

Configure App.xaml and MainWindow.xaml (and .cs) to handle MahApps.Metro

If you mean that you are importing the MahApps.Metro style resources into both your App.xaml and MainWindow.xaml, then that is unnecessary. Putting them in App.xaml ought to suffice.


This is what I tried, and it worked for me:

App.xaml:

<Application x:Class="WpfTest.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
  <Application.Resources>
    <ResourceDictionary>

      <!-- MahApps.Metro Resource Imports -->
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="/MahApps.Metro;component/Styles/Controls.xaml" />
        <ResourceDictionary Source="/MahApps.Metro;component/Styles/Fonts.xaml" />
        <ResourceDictionary Source="/MahApps.Metro;component/Styles/Colors.xaml" />
        <ResourceDictionary Source="/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
        <ResourceDictionary Source="/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
      </ResourceDictionary.MergedDictionaries>

      <!-- Global TextBox Style Override -->
      <Style TargetType="TextBox" BasedOn="{StaticResource MetroTextBox}">
        <Setter Property="Margin" Value="50" />
        <Setter Property="BorderBrush" Value="Crimson" />
      </Style>

    </ResourceDictionary>
  </Application.Resources>
</Application>

MainWindow.xaml:

<m:MetroWindow x:Class="WpfTest.MainWindow"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:m="http://metro.mahapps.com/winfx/xaml/controls"
               SizeToContent="WidthAndHeight">
  <TextBox m:TextBoxHelper.Watermark="Test" Width="300" />
</m:MetroWindow>

Result:

Screenshot of TextBox with Global Style Applied

Upvotes: 4

punker76
punker76

Reputation: 14611

I've tested this issue also without MahApps and became the same result (a base Style in a ResourceDictionary which is referenced in App.xaml).

After some trials and errors I found a solution which works with and without MahApps.

The trick is defining a base style with a key in a extra ResourceDictionary (can be also a separate one) and use this to define a base style which is now used everywhere.

<Application x:Class="WpfApplication16.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
             StartupUri="MainWindow.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>
                    <Style x:Key="BaseTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
                        <Setter Property="Background" Value="Goldenrod" />
                        <Setter Property="Margin" Value="5" />
                        <Setter Property="controls:TextBoxHelper.ClearTextButton" Value="True" />
                    </Style>
                </ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>

            <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseTextBoxStyle}" />

        </ResourceDictionary>
    </Application.Resources>
</Application>

Sample

<Window x:Class="WpfApplication16.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">

        <TextBox Margin="10" Text="Test" MinWidth="200" />

    </StackPanel>
</Window>

enter image description here

Hope this helps!

Upvotes: 0

Related Questions