I have a button that has two images attached to its DataContext.
The displayed image is bind to the button IsEnabled property.
Here is the XAML for the button:
<Button Name="SubmitButton" IsEnabled="{Binding IsSubmitEnabled}" Background="Transparent">
<Image Name="SubmitButtonImage" Height="50" Width="291" MinHeight="50" MinWidth="291">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSubmitEnabled}" Value="True">
<Setter Property="Source" Value="/Resources/startup/Submit_enabled.png"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsSubmitEnabled}" Value="False">
<Setter Property="Source" Value="/Resources/startup/Submit_disabled.png"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
Now instead of specifying the image in DataTrigger Value I want to use a template that is defined in the file like this:
<ControlTemplate x:Key="SubmitEnabledTemplate" TargetType="{x:Type Button}">
<Border
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Image Source="/Resources/startup/Submit_enabled.png"></Image>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="SubmitDisabledTemplate" TargetType="{x:Type Button}">
<Border
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Image Source="/Resources/startup/Submit_disabled.png"></Image>
</Border>
</ControlTemplate>
Any ideas how to do that?
Try a DataTemplate Trigger, here is an example which may be relevant:
<ItemsControl ItemsSource="{Binding Path=Groups}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl x:Name="cc" Content="{Binding}" ContentTemplate="{DynamicResource ItemTemplate}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsLeaf}" Value="False">
<Setter TargetName="cc" Property="ContentTemplate" Value="{DynamicResource GroupTemplate}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
See DataTemplate.Triggers property.
WPF has option to switch control template also
CODE:
<Window.Resources>
<ControlTemplate x:Key="SubmitEnabledTemplate" TargetType="{x:Type Button}">
<Border
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Image Source="/Resources/startup/Submit_enabled.png"></Image>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="SubmitDisabledTemplate" TargetType="{x:Type Button}">
<Border
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<Image Source="/Resources/startup/Submit_disabled.png"></Image>
</Border>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Button Grid.Row="0">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template"
Value="{StaticResource SubmitEnabledTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSubmitButtonEnabled}"
Value="False">
<Setter Property="Template"
Value="{StaticResource SubmitDisabledTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
Related
I have an Expander and it should receive the full width of the column but I cant get it to work.
I tried to add the Horizontal(Content)Alignment = stretch on the TextBlock and on the Expander itself even on the Grid, but it is not working.
What I need is that the Expander takes about 90% of the width and the rest are assigned to the buttons as in the following example:
I want to display e.g. a name and when you press on it, expands down and shows additional information
and if the buttons are pressed, then the commands behind the buttons will be executed (no commands are binded in the example).
<ListView
ItemsSource="{Binding log}"
SelectionMode="Multiple"
Style="{StaticResource ListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,0,0,1" BorderBrush="Gray">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Expander Grid.Column="0"
HorizontalAlignment="Stretch"
IsExpanded="{Binding Mode=TwoWay, Path=IsSelected, RelativeSource={RelativeSource AncestorType=ListBoxItem, Mode=FindAncestor}}"
Style="{StaticResource ExpanderStyle}">
<Expander.Header>
<TextBlock Text="{Binding Name}" Foreground="White"
HorizontalAlignment="Stretch" />
</Expander.Header>
<TextBlock
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Description}" />
</Expander>
<Button Grid.Column="1"
Style="{StaticResource IconButton}">
<Button.Background>
<ImageBrush ImageSource="../icons/edit.png"
Stretch="None" />
</Button.Background>
</Button>
<dialogButton:ConfirmButton Grid.Column="2"
Question="{x:Static language:Strings.confirm}"
Style="{DynamicResource IconButton}"
Margin="0,0,10,0">
<dialogButton:ConfirmButton.Background>
<ImageBrush ImageSource="../icons/delete.png"
Stretch="None" />
</dialogButton:ConfirmButton.Background>
</dialogButton:ConfirmButton>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Styles
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<ContentPresenter HorizontalAlignment="Stretch" Margin="0" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderStyle" TargetType="{x:Type Expander}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" CornerRadius="3" SnapsToDevicePixels="true">
<DockPanel>
<ToggleButton x:Name="HeaderSite" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" DockPanel.Dock="Top" FontStyle="{TemplateBinding FontStyle}" FontStretch="{TemplateBinding FontStretch}" FontWeight="{TemplateBinding FontWeight}" FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}" FontFamily="{TemplateBinding FontFamily}" Foreground="{TemplateBinding Foreground}" FontSize="{TemplateBinding FontSize}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" MinHeight="0" MinWidth="0" Margin="1" Padding="{TemplateBinding Padding}" Style="{StaticResource ExpanderDownHeaderStyle}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter x:Name="ExpandSite" DockPanel.Dock="Bottom" Focusable="false" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Visibility="Collapsed"/>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="true">
<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
</Trigger>
<Trigger Property="ExpandDirection" Value="Down">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Bottom"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Top"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource ExpanderDownHeaderStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I also tried things from the following Threads
wpf - Header of Expander fit contents width?
Problem here is that the Buttons are pushed out of the view
Best Solution would be if the Expander just takes the width of the column so that I can adjust the widths of the element by the Grid.ColumnDefinition.
The issue is that the item container, a ListViewItem does not stretch its content by default. You have to create an item container style in order to set the HorizontalContentAlignment to Stretch.
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
Here is a button which I styled, but I realized that there is no way for someone who uses the application to notice when button is mouse over / selected or something like that?
I just want some kind of notification when button is selected or whatever?
Any kind of solution will be acceptable for me so in case button is mouse hovered, or in case button is selected to notice user
that is that button!
Here is my current button:
<Button x:Name="btnOk"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
IsDefault="True"
Grid.Row="2"
Grid.Column="1"
FontSize="15"
Width="140"
BorderThickness="1"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="#0091EA"
Background="White"
Content="Ok!"
BorderBrush="#0091EA" Margin="5,10,0,10" HorizontalAlignment="Left" Click="btnPotvrdi_Click">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="BlueViolet"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
Specify the default background (White) in the Style and your trigger will work as expected:
<Button x:Name="btnOk"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
IsDefault="True"
Grid.Row="2"
Grid.Column="1"
FontSize="15"
Width="140"
BorderThickness="1"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Foreground="#0091EA"
Content="Ok!"
BorderBrush="#0091EA" Margin="5,10,0,10" HorizontalAlignment="Left" Click="btnPotvrdi_Click">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="White" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Green"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="BlueViolet"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
A "local" value takes precedence over a value set by a Setter in a Style: https://msdn.microsoft.com/en-us/library/ms743230(v=vs.110).aspx
I am making a wpf form(moved from winform a couple days ago), and i wanted to customize my textbox. I got the textbox to behave how i want it to, but now i cant give it input, and it does not respond at all when i click it. I think i broke it, anyways here is my code:
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,48,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" Foreground="White">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="BorderBrush" Value="#FF497AB4"/>
<Setter Property="Background" Value="#FF2E2E2E"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="OrangeRed"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
So what am i doing wrong? Thanks!
Try adding a Scrollviewer to your template, like this:
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
You've got some example templates here
The problem was that the template didn't have a ContentHost, so it would not render the contents. To add a ContentHost, you should add an element named "PART_ContentHost" as explained here
How can I change style (background and border) of the popup in AutoCompleteBox in Windows Phone 8, xaml, c#?
You have to edit the control template, as those properties in the default template are not styleable. You might want to make a new style, or you could just override the existing one. Here is the default style (in the Toolkit source under Themes/Generic.xaml):
<Style TargetType="controls:AutoCompleteBox">
<Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<ContentControl Content="{Binding}" Margin="8,7"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Padding" Value="6,0,6,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:AutoCompleteBox">
<Grid>
<TextBox
x:Name="Text"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
InputScope="{TemplateBinding InputScope}"
Opacity="{TemplateBinding Opacity}"
Padding="{TemplateBinding Padding}"
Style="{TemplateBinding TextBoxStyle}"/>
<Popup x:Name="Popup">
<ListBox
x:Name="Selector"
Background="White"
BorderBrush="{StaticResource PhoneTextBoxEditBorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
IsTabStop="False"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Opacity="{TemplateBinding Opacity}"
Padding="0,8"/>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So you could just hard-code a new color for the ListBox in the Popup, eg:
<ListBox
x:Name="Selector"
Background="Black"
BorderBrush="Red"
Alternately, you could make the border/background styleable, but the same color as for the TextBox:
<ListBox
x:Name="Selector"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
This way, styles you apply to instances of the control will apply to both the TextBox and the Popup:
<controls:AutoCompleteBox Background="Black" BorderBrush="Red" ... />
I have the following code which supposed to display a TreeView (the original code is more complicated, thus the complex control hirerchy):
<TreeView ItemsSource="{Binding TreeRoot}"
HorizontalAlignment="Left">
<TreeView.Resources>
<DataTemplate x:Key="CTemplate">
<Border >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<ToggleButton
Grid.Column="1"
x:Name="Expander"
HorizontalAlignment="Right"
ClickMode="Press"/>
<TextBlock Text="{Binding Name}"
Grid.Column="0" />
</Grid>
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasItems, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}" Value="False">
<Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<Style TargetType="{x:Type TreeViewItem}" x:Key="aaa">
<Setter Property="ItemsSource" Value="{Binding Children}"/>
<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded,Mode=TwoWay}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<StackPanel>
<Border Name="Bd"
Background="{TemplateBinding Background}">
</Border>
<ItemsPresenter x:Name="ItemsP" />
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsP"
Property="Visibility"
Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TreeView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeView}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<ItemsPresenter/>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemContainerStyle" Value="{StaticResource aaa}" />
<Setter Property="ItemTemplate" Value="{CTemplate}" />
</Style>
</TreeView.Resources>
</TreeView>
Could you please help me figure out why my items are not displayed?
(The page appears empty)
Thanks,
Li
You don't have anything showing the Header of the TreeViewItem:
<Style TargetType="{x:Type TreeViewItem}" x:Key="aaa">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<StackPanel>
<Border Name="Bd" Background="{TemplateBinding Background}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ItemsPresenter x:Name="ItemsP" />
</StackPanel>
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Above I added the ContentPresenter.