I'm using the latest MahApps WPF toolkit and I'm having a bit of trouble with applying my own styles onto its controls, precisely the PasswordBox.
I've defined the styles in a separate .xaml file which is included in the App.xaml file so that it is globally visible, across all .xaml files.
But when I use the style specified under a key the MahApps ClearTextButton refuses to appear on the control.
Here is my style:
<Style x:Key="DefaultPasswordBoxStyle"
TargetType="{x:Type PasswordBox}"
BasedOn="{StaticResource ResourceKey={x:Type PasswordBox}}">
<Setter Property="HorizontalContentAlignment">
<Setter.Value>Center</Setter.Value>
</Setter>
<Setter Property="FontSize">
<Setter.Value>16</Setter.Value>
</Setter>
</Style>
And its usage in a separate .xaml file:
<PasswordBox Margin="{StaticResource ControlMargin}"
controls:TextBoxHelper.ClearTextButton="True"
Style="{StaticResource DefaultPasswordBoxStyle}"
Width="200" />
If I delete the Style attribute the button shows as it is supposed but want to be able to apply my own styles also. It is actually visible in the XAML designer, which is funny. I tried DynamicResource, as well, but with the same results.
So to continue on from the original comments, you had a Type set as your Resource instead of pointing to a Key name. So once you gave your new custom template a proper path to find the original Style template as a BasedOn condition to inherit the rest of the MahApps style then the issue was resolved.
The VS underlining/not locating the resource thing, well I run into that all the time and I'm kind of convinced it's a defect in VS though I wouldn't mind knowing how to clear that off as well. It's annoying since sometimes it will have those errors in the IDE, sometimes it won't, lots of fun.
In the meantime, now that you have your template referencing the correct one as its base with the resource dictionaries referenced properly then all is well in the world again. Hope this helped, cheers!
Related
I have a NavigationView control with an AutoSearchBox displayed:
<NavigationView Style="{StaticResource CompactNavigationViewStyle}"
x:Name="NavigationView" OpenPaneLength="280"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"
AlwaysShowHeader="False">
<NavigationView.AutoSuggestBox>
<AutoSuggestBox PlaceholderText="Search" QueryIcon="Find" Width="235"
x:Name="SearchTxt" QuerySubmitted="OnSearch" />
</NavigationView.AutoSuggestBox>
For some page I don't want to show the Search (i.e SettingPage), so on NavigationView ItemInvoked event I added this code:
private void NavigationView_ItemInvoked(NavigationView sender,
NavigationViewItemInvokedEventArgs args)
{
if (!args.IsSettingsInvoked)
{
string tag = (args.InvokedItem as string);
switch(tag)
{
case "settingpage":
case "exportpage":
SearchTxt.Visibility = Visibility.Collapsed;
break;
default:
SearchTxt.Visibility = Visibility.Visible;
break;
}
// Code to load new page to Frame here
}
}
The AutoSuggestBox is hidden from NavigationView, but the Search icon still displayed on Compact mode, how to hide this icon too?
Unfortunately, what you are looking for does not appear to be possible with the NavigationView control. This is relatively new control, however, so Microsoft may be updating it in the future.
For the technical reason, setting a value to the AutoSuggestBox property does more than just add an AutoSuggestBox to the NavigationView; it also changes some other internals of the NavigationView (such as the one specifying showing that search icon when the pane is collapsed).
The AutoSuggestBox property is an optional property, and designed to contain a search box "to allow for app-level search". This suggests that it is designed to be always visible across the entire app when present (although I could see a reasonable argument being made for having it disabled on certain pages). But simply, it looks like this is a use case the control is not designed for.
As for some ideas for work-arounds:
Option 1
The one place you can freely put whatever content you want is the NavigationView.Footer. You can implement something like the above code, and then adjust the StackPanel's visibility property.
The main downside to this option, of course, is that the footer is stuck at the bottom, which may be an odd place to put a search bar. You also will need to give the StackPanel some visual styling to mimic the hover and click effects on the rest of the NavigationView.
<StackPanel Orientation="Horizontal"
Margin="10">
<TextBlock Style="{StaticResource HamburgerMenuIconStyle}"
Text=""></TextBlock>
<TextBlock Style="{StaticResource HamburgerMenuItemTextStyle}"
Text="Home"></TextBlock>
</StackPanel>
And then the supporting styles for the Page.Resources, so that the above bindings work (you may need to play around with the numbers for the margins and font sizes, but this looked good for me):
<Page.Resources>
<Style x:Key="HamburgerMenuIconStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"></Setter>
<Setter Property="FontSize" Value="18"></Setter>
<Setter Property="Margin" Value="5,0,0,0"></Setter>
</Style>
<Style x:Key="HamburgerMenuItemTextStyle" TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"></Setter>
<Setter Property="Margin" Value="15,0,20,0"></Setter>
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</Page.Resources>
Option 2
You can implement your own NavigationView, using a SplitView. This is actually not too difficult, and there is even a fantastic tutorial in the following link (which I have used for several personal projects): https://mva.microsoft.com/en-US/training-courses/windows-10-development-for-absolute-beginners-14541?l=4DLgEZ0qB_5705244527. Specifically see Video #22, if the link doesn't open that one.
Implementing your own works well enough for visual looks, and for navigational functionality. Unfortunately, however, the more advanced features in the built-in NavigationView control are considerably more time-consuming to implement, such as the built-in "Back" navigation support, and the built-in fluent design styling. You can wrap this into a UserControl or a custom Control, so that you can reuse it in other projects, but the initial time investment will still be high.
It is worth noting that the requirements you are imposing on your users by using a NavigationView in the first place should be considered (if you have not done so already):
The NavigationView was introduced in the Fall Creator's Update, so any users must have a version newer than that. Somewhere around 90% of users who have Windows 10 do, so this is pretty safe for most people.
The Back navigation functionality of the NavigationView was introduced even more recently, specifically in v10.0.17110.0. This is still in Windows Insider, and not generally released yet (I believe), so this functionality specifically may not be a good choice for a larger audience yet. The reason I point this out, is that to reach a larger audience, you would need to implement the back functionality yourself anyway, so the barrier to writing your own NavigationView may not be as high as it seems.
Hope that helps!
<NavigationViewItem
x:Name="NaviSearchItem"
Icon="Find"
Visibility="Collapsed" />
<NavigationViewItem x:Name="NaviSearchBarItem">
<AutoSuggestBox
x:Name="NaviSearchBar"
PlaceholderText="Search"
QueryIcon="Find" />
</NavigationViewItem>
You can surround the AutoSuggestBox with NavigationViewItem and place the Search Button above it. Then you need to set the visibility of NaviSearchBarItem instead of the AutoSuggestBox. This hides the AutoSuggestBox perfectly.
However, there is a tiny issue with this solution. When you click on the NaviSearchBarItem to open the Pane, the animation of tab (a blue pipe that indicates the selected item) will still slide to the NaviSearchBarItem, and then it disappears. The ideal solution should be that the blue indicator still remain on the original item. I don't know how to fix this.
I'm creating a new style for the TabControl including a new ItemContainerStyle for the items. The new style works fine, except that I need the possibility to add features to the ItemContainerStyle when using the style. In detail this is the Header property
<TabControl x:Name="myTabControl" SelectionChanged="myTabControl_SelectionChanged">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Header" Value="{Binding Title}"></Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
which works OK. But it overrides the style completely. the BasedOn property would help, but I don't have access to the key of the ItemContainerStyle since it is embedded in the TabControls' style. How can I simply update a property of the style without overriding the style completely?
Thanks
There is a bit of a difference in the way styles in WPF compared to css. In Wpf they work completely off of inheritance, this is the basic document on how styles work. So if a key is not provided for you I think you are out of luck when using the BasedOn inheritance.
However, Microsoft does provide a useful utility in Visual Studio Blend. In the Objects and Timelines Window you right click then select an "edit a style", This will do all the heavy lifting for you. If you are going to be doing a lot of small changes on the style I would suggest you make a copy, and give it a Key, then use the BasedOn property to make your small changes that you want.
I Hope this helps.
You can base your style on the implicitly applied default style:
<Style TargetType="TabItem" BasedOn="{StaticResource {x:Type TabItem}}">
So, I have this Window. On it, I'm creating a list of TextBlocks and TextBoxes in pairs. When you click on either, they will put a number in the corresponding TextBox, and set some values in the background. This all works well now.
I have the following XAML to create a custom Checkbox (as it has the behavior I'd like to use for this). My problem is that I want to bind different content into both the TextBlock and TextBox. For the TextBlock, I bound to the Content property, but I can't find a suitable option to satisfy the second binding. I considered placing it in the tag, but this didn't feel right, and in any case, I'm already binding an index value I require into there.
<Style x:Key="CustomCHK" TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<DockPanel LastChildFill="True">
<TextBox DockPanel.Dock="Right" Width="50" Height="30" />
<TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Feels like there should a simple solution to this, but I'm just trying to decide what's best. Do I create a custom checkbox class and just add a couple properties?
As always, I appreciate any direction you can offer me.
Unfortunately, there is no straightforward way to do this. I can see just two (somewhat flawed) workarounds:
Subclass CheckBox to suit your needs, and add the additional content properties that you need. The advantage is that this will fully enable your IDE's programming help for setting the content properties, and those properties will be typesafe. The downside is that your will need to add C# code for the sole purpose of declaring the additional content properties (i.e. without adding any "behavioral logic"), which somehow seems to conflict with a "clean" XAML-only for presentation approach.
You could try passing an array to the Content property, and then place several ContentPresenter instances in your control template, each of which bind to another item in the array. Binding property paths should support indexed access, though your code may become a bit verbose, as arrays in XAML have to be written explicitly by using the x:Array markup extension.
I am using GraphX in Winform project. I am trying to display labels besides the edges. I want to know what property do I have to set in order to display some text in the label.
I have tried setting the 'Text' property of DataEdge, and then calling
ShowAllEdgesLabels(true);
but it does not work this way. Going through the forums I have found that WPF has a way to bind this property to the visual control. The XAML code is as follows
<gxl:EdgeLabelControl x:Name="PART_edgeLabel" Content="{Binding Edge.Text, RelativeSource={RelativeSource TemplatedParent}}" />
Now the question is what is the equivalent of Winform to achieve this functionality.
I found a solution with the help of the admin at the host of GraphX (PantheR).
Basically, we need to add the hostControler for WPF in a windows form.
We need to add a custom XAML template in the resources folder.
We need to load the XAML as a new resource in the code, before we initialize the graph.
We need to add a line of code to merge the resources.
Then in the XAML code we do the binding as mentioned in the question. The code has been updated at the repository to reflect these changes.
The downfall of this solution is that, we need to provide a XAML resource file with the program, but thats just another resource (in my opinion).
For anyone that need some reference code from #ResVic's answer:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graphx="http://schemas.panthernet.ru/graphx/"
xmlns:local="clr-namespace:YOUR_NAME_SPACE">
...
<Style TargetType="{x:Type graphx:AttachableEdgeLabelControl}">
<Setter Property="ShowLabel" Value="False" />
</Style>
...
</ResourceDictionary>
The Show case demo is protentially helpful for figuring out what stuff the lib could do and how to tweak it to work.
According to MSDN, the standard way of setting your app theme is to set RequestedTheme="Dark" or RequestedTheme="Light" on the toplevel Application instance.
This works great for simple apps but many times I find myself wanting to change the theme of an individual page or even an individual control (e.g. a light-themed text edit page vs a dark-themed image viewer in the same app).
XAML controls have 10s or 100s of visual states and color definitions and setting each one of them by hand is tedious and difficult to get 100% right!
Is there an easy way to set a dark or light theme on an individual control?
For a XAML windows store app, the default look-and-feel of controls is defined in Common/StandardStyles.xaml. If you've ever looked at that file, you'll notice a ton of references like {StaticResource ApplicationForegroundThemeBrush}. Looks promising...
Unfortunately, these "theme brushes" aren't defined anywhere in your app, and there's no easy way to set a light or dark override for individual controls. However, there is an answer.
Fortunately, there's an excellent blog post by Joe White on the default theme colors, which I've turned into a resource dictionary that you can find here. Dropbox only does xml previews so you'll have to rename the file.
Copying these resources to your app won't help by itself though. To make use of them, you need to surgically override the default control styles to use them!
One way to do this is to create a new resource dictionary, e.g. at Common/CustomStyles.xaml, and merge that into the app's resources like so:
<Application
x:Class="My.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--
Styles that define common aspects of the platform look and feel
Required by Visual Studio project and item templates
-->
<ResourceDictionary Source="Common/ThemeColors.xaml"/>
<ResourceDictionary Source="Common/StandardStyles.xaml"/>
<ResourceDictionary Source="Common/CustomStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Notice that our default theme is Light. If we'd like to make a Dark-themed TextBlock, let's copy the visual style from StandardStyles.xaml and add it to our CustomStyles.xaml and make a few changes.
<Style x:Key="BasicRichTextStyleDark" TargetType="RichTextBlock">
<Setter Property="Foreground" Value="{StaticResource ApplicationForegroundThemeBrushDark}"/>
<Setter Property="FontSize" Value="{StaticResource ControlContentThemeFontSize}"/>
<Setter Property="FontFamily" Value="{StaticResource ContentControlThemeFontFamily}"/>
<Setter Property="TextTrimming" Value="WordEllipsis"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Typography.StylisticSet20" Value="True"/>
<Setter Property="Typography.DiscretionaryLigatures" Value="True"/>
<Setter Property="Typography.CaseSensitiveForms" Value="True"/>
</Style>
Notice that we have appended Dark to the style name and the theme brush definitions! You can do this via find and replace "ThemeBrush}" => "ThemeBrushDark}" in your CustomStyles.xaml file.
Now you can create a dark-themed text block like so:
<TextBlock Style="{StaticResource BasicRichTextStyleDark}"/>
Of course, you can use this technique for any other type of control as well. A little tedious, but the results are correct and it's not nearly as bad as trying to define every color manually!
There's no magic here. We're just defining some colors and overriding a default style with one that we copy-pasted and modified to use our colors.
A solution that surprisingly does not seem to be mentioned is just to use RequestedTheme="Dark" or RequestedTheme="Light" on the individual control elements.
I do that for an app where I needed to set some appbarbuttons to the dark setting (which is white foreground) - because the Foreground property did not set both the circle and the glyph itself to white:
<AppBarButton Label="Reload all articles" RequestedTheme="Dark" >
This way, I just force the control to use the theme I decide.
In folder Common you have a StandardStyles.xaml file.
Here you can find all standard styles default for Metro Applications.
You need to uncomment styles what you want to use and add to control as StaticResource.
I've also faced the same problem while Designing my App "Contact Book", because i also wanted the change between Dark & Light themes. For your que : "How do I mix Light and Dark themes in a C#/XAML Windows Store (Metro UI) App?", I have a superb solution.
I have made two pages with same code & same content. I added both those pages one above another and then I've made a dynamic change between those two kind of themes Light & Dark. I gave an option to user whether they want Dark layout or Light layout & as per user's choice I've applied the theme. I succeeded in this case.
Second solution:
If you want dynamic look and feel for your application, then you have
to made your own static layout type and then you can bind your that
static resource to the page on which you want to apply that kind of
style.
pardon if you don't find your answer here, but i thought it might help you to dynamically change between "Dark" & "Light" themes setting in your win 8 metro app.