How to change visual behavior of a button in WPF? - c#

I noticed that on Windows 10, the appearance of controls shown by the OS looks much more appealing than the defaults on Winforms/WPF. For example, The selected OS button has a thicker blue border, and a more interactive "feel" to it, while the default WPF button appears as a simple grey box:
OS:
WPF:
Is there a way to somehow change the "theme" of a button in WPF to behave similarly to the most OS-displayed buttons, without having to implement this behaviour manually?

You can get similar button styles using Windows UWP.
In WPF, you can check out the Modern UI(MUI) in MSDN site.
It can produce similar results. I have been working with mui for a couple of months and it really helped me to satisfy my client who wanted to have a Windows 10 like UI experience. I had to create tiles like in start menu also. MUI did a great job for me.
Get the MUI from Github. Modern UI for WPF
Also I had tried devexpress and telerik controls. Have a look at them too.

You can use DevExpress to get themes for your form. Or you can implement your own by adding borders around every button and change its Color/Visibility on MouseDown and MouseUp event handlers

Define a Style within Window.Resources with TargetType="Button" so that it affects all the buttons in that window. For example, although the default WPF button has mouseover colour change and a focus rectangle, it does not move "inwards" on MouseDown, so this example shows how to do this:
<Window.Resources>
<!--A Style that affects all Buttons-->
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property= "RenderTransform">
<Setter.Value>
<TransformGroup>
<ScaleTransform ScaleX="0.99" ScaleY="0.99"/>
<TranslateTransform X="2" Y="2"/>
</TransformGroup>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness">
<Setter.Value>
<Thickness Left="2" Right="2" Top="2" Bottom="2"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Insert this after the Window attributes and before the Grid or other container tag.

Related

How to work with control inheritance

I use Telerik as a WPF library. We can apply a theme on Telerik controls using application Theme (i.e. theme manager). For Microsoft controls we can set a property to make the theme apply.
The problem is : I don't want to write this line :
<Style TargetType="{x:Type CheckBox}">
<Setter Property="telerik:StyleManager.Theme" Value="{Binding Source={StaticResource Settings}, Path=Default.Theme}" />
</Style>
for every type: CheckBox, TextBlock, TextBox etc.. for maintenance purpose.
If I target <Style TargetType="{x:Type Control}"> inheritance doesn't work well.
Base class of CheckBox is Control but when I set property on every control it doesn't set property on every child of control too. Any idea how i can do this?

Windows phone 8: navigation animation

How to animate navigation process like "pushViewController" in iOS.
I mean animage navigation from left to right.
Thank you.
You have to use the Windows Phone Toolkit to animate navigation between pages. There's no builtin feature to do such a thing.
You will have to configure animations in each page you want an animation to happen (You will also be able to put these configurations into Styles to share them across your App).
You'll find a great step by step guide in here. (It was intended for WP7 at first but it's still valid for WP8)
Finally, the Style corresponding to the effect that you are trying to reproduce should look like this one :
<Style x:Key="TransitionPageSlideStyle" TargetType="phone:PhoneApplicationPage">
<Setter Property="slt:TransitionService.NavigationInTransition">
<Setter.Value>
<slt:NavigationInTransition>
<slt:NavigationInTransition.Backward>
<slt:SlideTransition Mode="SlideRightFadeIn"/>
</slt:NavigationInTransition.Backward>
<slt:NavigationInTransition.Forward>
<slt:SlideTransition Mode="SlideLeftFadeIn"/>
</slt:NavigationInTransition.Forward>
</slt:NavigationInTransition>
</Setter.Value>
</Setter>
<Setter Property="slt:TransitionService.NavigationOutTransition">
<Setter.Value>
<slt:NavigationOutTransition>
<slt:NavigationOutTransition.Backward>
<slt:SlideTransition Mode="SlideRightFadeOut"/>
</slt:NavigationOutTransition.Backward>
<slt:NavigationOutTransition.Forward>
<slt:SlideTransition Mode="SlideLeftFadeOut"/>
</slt:NavigationOutTransition.Forward>
</slt:NavigationOutTransition>
</Setter.Value>
</Setter>
</Style>

Setting Design Time Size for Custom Control

How do you set the Design Time Width and Height of a custom control?
I have created a custom ItemsControl, i.e. (contents of generic.xaml)
<Style TargetType="{x:Type MyItemsControl}" >
<Setter Property="Height" Value="24" />
<Setter Property="Width" Value="160" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyItemsControl}" >
<Grid>
...
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
...
</Style>
And it works all nicely and all, however if I drag the control from the ToolBox onto my window the default size of my control is: Height = 100 and Width = 200. How do I set the design time size so that when I drag the control from the Toolbox to window the default size is 24 and 160 respectively?
May b it helps u..........
for that firstly u have to make ur own controls by inheriting it with
original controls and set Hieght,width and whatever you want in your
custom control .........after this when u drag ur own made control
form toolbox to ur form it will set by ur way whatever u wanted.......
This is a setting within Visual Studio itself, and there doesn't seem to be a way to change it, nor is Microsoft planning on changing it.
Source: A user reported this issue to Microsoft online and a Microsoft employee responded and marked the issue as "Won't Fix".

Allowing Copy/Paste for XamDataGrid across application

I'm working on an application that had many infrgistics XamDataGrids. I'd like to at least provide Copy to clipboard abilities on them. This can easily be achieved in the XAML for each grid, with:
<igDP:XamDataGrid DataSource="{Binding}" >
<igDP:XamDataGrid.FieldLayoutSettings>
<igDP:FieldLayoutSettings AllowClipboardOperations="Copy"/>
</igDP:XamDataGrid.FieldLayoutSettings>
</igDP:XamDataGrid>
However, I would like all XamDataGrids in the application to allow this Copy to clipboard feature. I thought styling would be the answer, but for some reason, this does not work:
<Style TargetType="{x:Type igDP:FieldLayoutSettings}">
<Setter Property="AllowClipboardOperations" Value="Copy" />
</Style>
I've tried many variations on the above, but nothing seems to take, and there are no error messages. Any help would be really appreciated.
This is untested but perhaps you require the fully qualified name as below: (including the XamDataGrid.)
<Style TargetType="{x:Type igDP:XamDataGrid.FieldLayoutSettings}">
<Setter Property="AllowClipboardOperations" Value="Copy" />
</Style>
This question is old, but I just ran across it.
Anyway, the TargetType of your style will be XamDataGrid.
The property you are setting is FieldLayoutSettings.
<Style TargetType="{x:Type igDp:XamDataGrid}">
<Setter Property="FieldLayoutSettings">
<Setter.Value>
<igDp:FieldLayoutSettings AllowClipboardOperations="Copy"/>
</Setter.Value>
</Setter>
</Style>
Is this style defined in a place (like App.xaml) where every XamDataGrid can inherit it?
Have you tried defining this style in the same XAML file as a XamDataGrid that might use it? I would start by seeing if you could make this work as a local style in one specific place.

Focus-dependent text change for TextBoxes in WPF

I'm writing an application in WPF using the MVVM-pattern and will really often use TextBoxes.
I don't want to use labels for the user to know user what the text box is for, i.e. I don't want something like this:
<TextBlock> Name: </TextBlock>
<TextBox />
Instead, I would like the TextBox to contain its own label. Statically, you would express it like this:
<TextBox>Name</TextBox>
If the cursor is displayed in the textbox, i.e. the TextBox gains focus, I want the description text to disappear. If the TextBox is left empty and it loses the focus, the description text should be shown again. It's similar to the search textbox of StackOverflow or the one of Firefox. (please tell me if your not sure what I mean).
One TextBox's label may change at runtime, dependending on e.g. a ComboBox's selected element or a value in my ViewModel. (It's like in Firefox's search TextBox, if you select google from the search engins' menu, the TextBox's label changes to "Google", if you select "Yahoo" its set to "Yahoo"). Thus I want to be able to bind the label's content.
Consider that I may already have a Binding on the Text-Property of the TextBox.
How can implement such a behaviour and make it reusable for any of my TextBox's? Code is welcome but not needed; a description of what to do is enough.
Thank you in advance.
Here is a style I think is exactly what you are looking for, and it's pure XAML.
<Style x:Key="WatermarkTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1" BorderBrush="Silver">
<Label x:Name="TextPrompt"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Tag}"
Background="{TemplateBinding Background}" Visibility="Collapsed"
Focusable="False" Foreground="Silver"/>
</Border>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="Black"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"/>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="BorderBase" Value="Black"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage is:
<TextBox Style="{StaticResource WatermarkTextBox}" Tag="Full Name"/>
where Tag is the help message you want to show.
You could clean up this style for your own use, but the most important part is the which controls hiding/showing the helper text.
It's worth noting as well, there is already a DependencyObject available for storing the helper text, so you don't need to create your own with this method.
FrameworkElement.Tag is available for holding arbitrary information about this element. That's why we set the Tag property:
http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.tag.aspx
You could derive from TextBox and implement your behaviour. The TextBox offers the events GotFocus/LostFocus (or the methods OnGotFocus/OnLostFocus respectively) which should help. You also should consider offering a new DepedencyProperty, so you can define the default text in xaml and bind it to other controls/resources etc.
To amplify on my suggestion about using an adorner.
An Adorner is basically an element, rendered on its own layer, that appears over/around another element. For instance, if you implement validation in a binding, the red box that decorates an invalid control is an adorner - it's not part of the control, and it can be (and is) applied to all kinds of controls. See the Adorners section of the WPF docs for a simple but clear example.
I thought of an Adorner for a couple of reasons. The principal one is that the behavior you're describing might not necessarily be confined to a TextBox. You might, for instance, want to have a ComboBox exhibit the same behavior. Implementing an Adorner would give you a consistent way to implement this functionality across multiple controls (though it doesn't make sense in, say, a CheckBox or a ProgressBar). A second is that you wouldn't have to do anything to the underlying control more elaborate than implementing triggers to display and hide the Adorner in response to focus events. Adorners are a bit of a pain in the butt to implement, but it's worth knowing how to.
All that said, I like mattjf's answer a lot more than I like mine. The only disadvantages I see with that approach are 1) It only works with the TextBox; you need to implemnent a new version of the style every time you want to use the approach on another control, 2) I may just be engaging in magical thinking, but every time I ever used the Tag property in WinForms it told me (once I learned to listen) that I was building something fragile. I don't know for sure that this is also true in WPF, but I bet it is.
My comment on using the bound Text property probably needs amplification. If you use the Text property to store the field label, then you've got a number of hard-to-solve problems. First, since it's a bound property, changing its value in the TextBox will change it in the source. So now your source needs to know a lot of information about the state of the UI - does the control currently have the focus? If the value of the Text property is Foo, does that mean that the label is Foo, or the user typed in Foo? There are probably ways that you can manage this, but the best way to manage it is to not have to.
(One other problem with this paradigm: What should be the behavior be if the user wants the value of the TextBox to be the empty string?)

Categories