please apologize me for my weakness in English.
I'm new to WPF , And i have a issue here as question title.
I tried to Implement a WPF User Control as button. but when i want to use the button on my app. i got error. here is my code & error.
User Control XAML Code :
<UserControl x:Class="AADControls.Buttons.Warning"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AADControls.Buttons"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<LinearGradientBrush x:Key="aad-warning-back-brush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF0F200"/>
<GradientStop Offset="1" Color="#FFFF8800"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="aad-warning-border-brush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF0F200"/>
<GradientStop Offset="1" Color="#FFFF8800"/>
</LinearGradientBrush>
</UserControl.Resources>
<Button Name="BtnWarning" Width="250" Height="50"
Content="AAD Button">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="AADBorder"
CornerRadius="10"
BorderThickness="4"
BorderBrush="{StaticResource aad-warning-border-brush}"
Background="{StaticResource aad-warning-back-brush}">
<ContentPresenter Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.1" ScaleY="1.1"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.0" ScaleY="1.0"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="true">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Opacity="0.8" Direction="135"
ShadowDepth="3" BlurRadius="1" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</UserControl>
My Usage of User Control :
<Window x:Class="DepaSOS.Pages.wndInitialize"
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:AAD="clr-namespace:AADControls.Buttons;assembly=AADControls"
xmlns:local="clr-namespace:DepaSOS.Pages"
mc:Ignorable="d"
Title="launch-n-Initialization"
WindowStartupLocation="{StaticResource WSL}">
<AAD:Warning Grid.Row="11" Grid.ColumnSpan="3"/>
Now the problem is Until i Use
<AAD:Warning Grid.Row="11" Grid.ColumnSpan="3"/>
Every thing is ok and the content shown is a default content, which set in the user control.The appearance of my control is like this Image :
But, If i just add Content Property to my button like this
<AAD:Warning Grid.Row="11" Grid.ColumnSpan="3" Content="Bla Bla Bla"/>
, every things about style goes wrong like this Image :
The XAML inside the <UserControl>...</UserControl> element is the Content of the UserControl. By default, it contains a Button. You are replacing the button with text, so you see the text instead of the button. You aren't losing the button's style. You're losing the whole button.
You are doing nothing that could possibly place the Content of the usercontrol inside a button. If you want to do that, you want to set the UserControl's template: The template determines how the content is presented (your own button template demonstrates just that). Like this:
<UserControl
x:Class="AADControls.Buttons.Warning"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AADControls.Buttons"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Content="AAD Button"
>
<UserControl.Resources>
<LinearGradientBrush x:Key="aad-warning-back-brush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF0F200"/>
<GradientStop Offset="1" Color="#FFFF8800"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="aad-warning-border-brush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="0" Color="#FFF0F200"/>
<GradientStop Offset="1" Color="#FFFF8800"/>
</LinearGradientBrush>
</UserControl.Resources>
<!-- This template contains the XAML you had for the Content. -->
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Button
Name="BtnWarning"
Width="250"
Height="50"
Content="{TemplateBinding Content}"
>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border
Name="AADBorder"
CornerRadius="10"
BorderThickness="4"
BorderBrush="{StaticResource aad-warning-border-brush}"
Background="{StaticResource aad-warning-back-brush}"
>
<ContentPresenter
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.1" ScaleY="1.1"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="1.0" ScaleY="1.0"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsMouseCaptured" Value="true">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect
Opacity="0.8"
Direction="135"
ShadowDepth="3"
BlurRadius="1" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</ControlTemplate>
</UserControl.Template>
</UserControl>
Notice a few things:
The XAML you had for the content is now all in the UserControl's ControlTemplate
The Content of the Button is now Content="{TemplateBinding Content}". That means, "Find the Content property of the control the template is applied to, and use its value here."
We are now setting the Content property of the UserControl to "AAD Button" -- the text you formerly were assigning to the button's content.
Content="AAD Button"
That will be the default content of the usercontrol, which will be displayed in the button unless you give it some different content. Here, for example, you're giving it the content "Bla Bla Bla", which will be displayed in the button.
<AAD:Warning Grid.Row="11" Grid.ColumnSpan="3" Content="Bla Bla Bla"/>
Related
I have a requirement where I need a button which will let the user tap and swipe down/up in order to expand/collapse the control above the button. Something like in this image:
How can I achieve it in xaml?
You can create Template for Header and put an image from your question into HeaderTemplate. Let me show an example:
<Grid>
<Grid.Resources>
<Style TargetType="Border" x:Key="FooBorderStyle" >
<Style.Resources>
<LinearGradientBrush x:Key="ABackBrush" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Color="#EF3132" Offset="0.1" />
<GradientStop Color="#D62B2B" Offset="0.9" />
</LinearGradientBrush>
</Style.Resources>
<Setter Property="Background" Value="{StaticResource ABackBrush}"/>
</Style>
<DataTemplate x:Key="titleTemplate">
<Border Style="{StaticResource FooBorderStyle}" Height="24">
<Image Source="../Images/yourImage.png"
Margin="4 0"
VerticalAlignment="Center"/>
</Border>
</DataTemplate>
<Style TargetType="{x:Type Expander}">
<Setter Property="HeaderTemplate" Value="{StaticResource titleTemplate}"/>
</Style>
</Grid.Resources>
<Expander Name="hcontCtrl" Header="This is the header.">
<StackPanel>
<TextBox>This is a textbox</TextBox>
<Button>A button</Button>
</StackPanel>
</Expander>
</Grid>
i have one button and i set button background style with LinearGradientBrush. everything works fine but when i run button and press click on button then gradient color is showing ob button with bit of animation but i have not write anything for animation for button background style.
here is my full code
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<Button Content="Button" Height="23" Name="button1" Width="75">
<Button.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFD9EDFF" Offset="0"/>
<GradientStop Color="#FFC0DEFF" Offset="0.445"/>
<GradientStop Color="#FFAFD1F8" Offset="0.53"/>
</LinearGradientBrush>
</Button.Background>
</Button>
</DockPanel>
</Window>
i want that when user click on button then gradient animation anything like will not start on button. please guide me. thanks
You need to redefine button style, You can do it using ControlTemplate. Here is example how to write reusable style that redefines button.
I have added also an example how to implement color change on IsPressed event.
<Window x:Class="ColorTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<LinearGradientBrush x:Key="ButtonBackground" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFD9EDFF" Offset="0"/>
<GradientStop Color="#FFC0DEFF" Offset="0.445"/>
<GradientStop Color="#FFAFD1F8" Offset="0.53"/>
</LinearGradientBrush>
<Style x:Key="SimpleButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border Background="{StaticResource ButtonBackground}" VerticalAlignment="Stretch" CornerRadius="2" HorizontalAlignment="Stretch"/>
<Border x:Name="BorderPressed" Opacity="0" Background="Blue" VerticalAlignment="Stretch" CornerRadius="2" HorizontalAlignment="Stretch"/>
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="MainContent" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="BorderPressed" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Window.Resources>
<DockPanel>
<Button Content="Button" Height="23" Name="button1" Width="75" Style="{StaticResource SimpleButtonStyle}"/>
</DockPanel>
This happens because of the buttons default style.
You need to set a new Style.
EDIT :
<Button Content="Button" Height="23" Name="button1" Width="75">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFD9EDFF" Offset="0"/>
<GradientStop Color="#FFC0DEFF" Offset="0.445"/>
<GradientStop Color="#FFAFD1F8" Offset="0.53"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Microsoft_Windows_Themes:ButtonChrome>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button.Style>
</Button>
If you want to have this style more than once use it as a resource:
Putting it to sets you this style for every button in your Window.xaml
Moving the style to a higher scope like App.xaml applies the style for every button in your application
I want to create a custom WPF dropdown menu, so I created a User control which contains a ToggleButton and a Popup control. The popup appears when I click on the button.
Now I want to add a mouse hover effect on the menu items in the popup: but the LinearGradientBrush is not working with alpha channels:
<UserControl.Resources>
...
<Style x:Key="SubMenuItemStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="MenuItem">
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" ClipToBounds="True">
<Rectangle x:Name="rectangle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="{TemplateBinding BorderBrush}" StrokeThickness="{TemplateBinding BorderThickness}"
Fill="{TemplateBinding Background}" />
<StackPanel>
<TextBlock x:Name="text" Text="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}" />
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Stroke" TargetName="rectangle" Value="#30000000"/>
<Setter Property="Fill" TargetName="rectangle">
<Setter.Value>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,1">
<GradientStop Color="#10000000" Offset="0"/>
<GradientStop Color="#10FFFFFF" Offset="1"/>
<!-- Not works... -->
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" TargetName="text" Value="#FF9A9A9A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<Controls:ToggleImageButton Style="{DynamicResource ArrowMenuStyle}" x:Name="imageButton" Height="21" />
<Popup x:Name="popup" PlacementTarget="{Binding ElementName=imageButton}" Placement="Bottom" StaysOpen="False" IsOpen="{Binding ElementName=imageButton, Path=IsChecked}">
<ItemsControl ItemsSource="{Binding MenuCommands}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<MenuItem Header="{Binding Name}" Command="{Binding Command}" Background="{Binding ElementName=popupMenuControl, Path=MenuBackground}" Foreground="{Binding ElementName=popupMenuControl, Path=MenuForeground}" Click="MenuItem_Click" Style="{StaticResource SubMenuItemStyle}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Popup>
</Grid>
When I set the GradientBrush to this, everything works fine:
<LinearGradientBrush EndPoint="0,0" StartPoint="1,1">
<GradientStop Color="Green" Offset="0"/>
<GradientStop Color="Yellow" Offset="1"/>
</LinearGradientBrush>
But it seems the Alpha channel breaks the whole thing, and what I see is a black rectangle.
...Any idea?
If I put the MenuItems inside a Menu container, the Menu overrides my styles...
Thanks in advance!
have you set AllowsTransparency to true?
I was wondering if it is possible to make a custom shape custom control.
I need to make control which contains textbox, however the control must have a shape of triangle or sth more sophisticated than regular rectangle/square.
Short answer is yes.
Long answer is reading up on WPF Control Styles:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640"
Height="480">
<Window.Resources>
<Style x:Key="TextBoxSample" TargetType="{x:Type TextBox}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Ellipse
x:Name="Border"
Stroke="#FF393785"
StrokeThickness="2"
>
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.25,0.25" RadiusY="0.75" RadiusX="0.75">
<GradientStop Color="White" Offset="0.2"/>
<GradientStop Color="#FF2EC452" Offset="0.5"/>
<GradientStop Color="#FF606060" Offset="1"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
<!-- The implementation places the Content into the ScrollViewer. It must be named PART_ContentHost for the control to function -->
<ScrollViewer
x:Name="PART_ContentHost"
Background="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Fill" Value="#000" TargetName="Border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<TextBox
Style="{StaticResource TextBoxSample}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="TextBox"
Width="180"
Height="180"
/>
</Grid>
</Window>
So the thing is that I have a main ControlTemplate which defines the most basic stuff for the new button look we're designing. But I want to do 3 other control templates for this button so we can set different colors in those; but I don't want to copy paste the main ControlTemplate and change the color there, instead I want to "inherit" from that (like with the BasedOn property in Style) and change the color in the inherited ControlTemplate.
Is this possible?
Thanks!
Found the solution. You don't extend ControlTemplates, instead you define all the basic behavior you want, and then you let either a style or the control itself modify it. Take the example below for instance. The ControlTemplate sets the OpacityMask and the round corners for my rectangle, the Styles sets the color of the background for each button (with help of a TemplateBinding), and there's my solution:
<Window.Resources>
<ControlTemplate x:Key="BaseMainButtonTemplate" TargetType="{x:Type Button}">
<Grid TextBlock.Foreground="White" TextBlock.FontFamily="Calibri">
<Rectangle Stroke="#FFE8E6E6" x:Name="rectangle" RadiusX="14.5" RadiusY="14.5" Fill="{TemplateBinding Property=Background}"> <!-- This TemplateBinding takes the color set by the style and applies it to the rectangle. Doing it this way, allows the style to modify the background color -->
<Rectangle.OpacityMask>
<LinearGradientBrush EndPoint="0,1" SpreadMethod="Reflect">
<GradientStop Offset="0" Color="Transparent"></GradientStop>
<GradientStop Offset="1" Color="Gray"></GradientStop>
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<!-- OpacityMask when it's Focused, Defaulted and Mouse is over -->
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="OpacityMask" TargetName="rectangle">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" SpreadMethod="Repeat">
<GradientStop Offset="1" Color="Transparent"></GradientStop>
<GradientStop Offset="0" Color="Gray"></GradientStop>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<!-- OpacityMask when it's pressed -->
<Trigger Property="IsPressed" Value="True">
<Setter Property="Stroke" TargetName="rectangle">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF223472" Offset="0"/>
<GradientStop Color="#FFF2F0F0" Offset="0.911"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="StrokeThickness" TargetName="rectangle" Value="3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="BlueButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue" />
<Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}">
</Setter>
</Style>
<Style x:Key="RedButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
<Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}">
</Setter>
</Style>
<Style x:Key="GreenButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Green" />
<Setter Property="Template" Value="{StaticResource BaseMainButtonTemplate}">
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
<Button Style="{StaticResource BlueButtonStyle}" Height="30" Content="Test">
</Button>
<Button Style="{StaticResource RedButtonStyle}" Height="30" Content="Test">
</Button>
<Button Style="{StaticResource GreenButtonStyle}" Height="30" Content="Test">
</Button>
</StackPanel>
</Grid>
Alternately you can define a "DynamicResource" reference to any dependency property in your Control Template and have it go resolve it's value given the presence of available resources.
For example, you can set Background="{DynamicResource SomeBrushColorVariable}"
Then SomeBrushColorVariable can change given different ResourceDictionaries that are merged into your App.xaml file or even set by the user given some user preferences display setting or color scheme.